Observera att denna sida är under utveckling!

Lektion 6: Listor och tupler
Denna lektion innehåller Obligatorisk uppgift 2 (OU2)

Moment: Mer systematisk genomgång av listor och tupler
Begrepp som introduceras: Listor och tupler
Arbetssätt: Arbeta gärna tillsammans med någon, men skriv egen kod. Diskutera med varandra!

Försök svara på de frågor som har givna svar innan du tittar på svaret. Fråga handledarna om det är något svar du inte förstår!

Tips: Använd debuggern

Uppskattad arbetstid: Schemalagd handledningstid inkl redovisning: 6 timmar. Utöver det räkna med eget arbete med lika många timmar.
Redovisning: Obligatorisk redovisning av uppgifterna enligt kursens hemsida.
Notera att den pythonkod du redovisar skall följa kodningsreglerna
Speciellt:
  • Strukturen på en python-fil: import-satser överst, sedan funktions-definitioner, sist funktionsanrop.
  • Ingen "lös" kod mellan funktions-definitionerna, all lös kod samlas till efter funktions-definitionerna.
  • Rimliga variabelnamn.
  • Inga globala variabler.
  • Utnyttja redan givna funktioner eller funktioner du redan har skrivit

  • Se till att ha legitimation, eftersom redovisningen är en examination
  • Du förklarar din kod individuellt
  • Vad som skulle hända om man gjorde ändringar i koden
  • Vara beredd på frågor från uppgiftstexten
  • Koden måste inte bara fungera, den måste vara tydlig också
  • Vid redovisningarna kan ges extra frågor och kodningsuppgifter
  • Anteckna namnet på personen som du redovisat för!
Backup: När du arbetar på egen dator måste du se till att det löpande görs backup på de filer (py-filer) som du skapar under kursens gång. Om du har filerna enbart lagrade på din dator finns risk att allt försvinner vid ett datorhaveri eller vid stöld.
Samarbete, fusk och plagiat:
  • Muntligt samarbete är tillåtet och rekommenderas.
  • Men den kod du redovisar skall du skriva helt själv, förutom given kod som finns på kursens hemsida.
  • Du får INTE på något sätt dela med mig av kod/svar till någon annan, förutom det muntliga samarbetet.
  • Du får INTE ta del av kod/svar någon annan på något sätt delar med sig av, förutom det muntliga samarbetet.
  • Vid misstanke om fusk eller plagiat, precis som vid annan examination, kan detta anmälas till universitetets disciplinnämnd.

Listor

Vi har redan använt listor en del men i denna lektion ska vi gå igenom dem mer systematiskt.

Detta är ett av de viktigaste verktygen i Python med ett stort användningsområde. Det innefattar bland annat det som i många andra språk kallas för arrayer men är mer generellt än dessa brukar vara.

En lista består av ett antal element av godtycklig datatyp.

Exempel:

Konstruktion av listor

En lista kan skapas genom att man, som i exemplen ovan, räknar upp elementen inom [ ]-parenteser:

fib = [1, 1, 2, 3, 5, 8]

Elementen får index från 0 och uppåt. För att nå enskilda element kan man också använda index-värdet omgivet av [ ]-parenteserna.

Operatorn = samt metoderna append och insert kan användas för att ändra listan.

ExempelUtskriftKommentar
fib = [1, 1, 2, 3, 5, 8] print(fib) [1, 1, 2, 3, 5, 8]
print(fib[3]) print(fib[2] + fib[5]) 3 10 Åtkomst av enskilda element m h a [ ]. Första index är alltid 0.
fib.append(12) print(fib) [1, 1, 2, 3, 5, 8, 12] Metoden append lägger till ett element sist.
fib[6] = 13 print(fib) [1, 1, 2, 3, 5, 8, 13] Ett enskilt element kan ändras med tilldelningsoperatorn.
fib.insert(0, 0) print(fib) [0, 1, 1, 2, 3, 5, 8, 13] insert(index, värde) skjuter in ett nytt värde på angivet index.
fib.pop(4) print(fib) [0, 1, 1, 2, 5, 8, 13] pop(index) tar bort element på angivet index.

Man kan använda negativa index för att referera element i slutet av listan. Index -1 står för det sista, -2 för det näst sista etc.

ExempelUtskrift
fib.append(fib[-1] + fib[-2]) print(fib) [0, 1, 1, 2, 3, 5, 8, 13, 21]
for i in range(3): fib.append(fib[-1] + fib[-2]) print(fib) [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

Arbeta med listor

Det finns flera standardfunktioner för listor, bl a: len för antalet element, max och min för största och minsta, sum för summan samt sorted som returnerar en ny lista som är sorterad. Alla dessa utom den första kräver att elementen i listan är "jämförbara" t ex antingen alla tal eller alla strängar.

ExempelUtskriftKommentar
m = [1, 3, 0.5, 4, 3.5, 8] print(len(m)) 6
print(max(m), min(m), sum(m)) 8 0.5 20.0
print(sorted(m)) print(m) [0.5, 1, 3, 3.5, 4, 8] [1, 3, 0.5, 4, 3.5, 8]
Ursprungslistan oförändrad.
print(sorted(['Ärlig', 'Eva', 'Åke'])) ['Eva', 'Ärlig', 'Åke'] Obs: Fel ordning på 'Å' och 'Ä'.
sorted(['x', 5]) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: '<' not supported between
instances of 'int' and 'str'
Datatyperna int och str är inte jämförbara.

Övningar

  1. Skriv en funktion mean(m) som beräknar och returnerar medelvärdet av talen i listan m! Vad händer om listan innehåller strängar? Lösningsförslag
    # Funktionen har en lista m som parameter
    def mean(m):
        # returnera summan av elementen i listan delat med listans längd
        return sum(m)/len(m)
    
  2. Skriv en funktion median(m) som beräknar och returnerar medianen av talen i listan m! Medianen är det tal som kommer i mitten om man sorterar talen. Om antalet tal är jämnt så definierar vi det närmast över mitten som median. Lösningsförslag
    # Funktionen har en lista m som parameter
    def median(m):
        l = sorted(m)     # Sortera m i stigande ordning till en ny lista l
        # Mittersta elementet i listan l är medianen
        # len(l)//2 är index för detta element
        return l[len(l)//2]  # Returnera det mittersta elementet
    

for-satsen på listor

För att iterera över elementen i en lista passar for-satsen bra.

Exempel: Summera alla negativa element i en lista med tal.

m = [-1, 3, 5, -3, 3, -8] sum = 0 for x in m: # Loopa igenom alla element x if x < 0: # Om x < 0 sum += x # summera elementet print(sum) # Skriver -12

Övningar

  1. Givet en lista med tal. Skriv kod som konstruerar en ny lista utan de negativa talen. Lösningsförslag
    m = [-1, 3, 5, -3, 3, -8]
    n = []              # Skapa en tom lista
    for x in m:         # loopa igenom elementen x i listan m
        if x >= 0:      # Om elementet x är >=0
            n.append(x) # Lägg det till listan n
    print(n)            # Skriver [3, 5, 3] efter loopen
    
  2. Skriv en funktionen between(lista, low, high) som skapar och returnerar en lista av de element i lista som ligger mellan low och high. Lösningsförslag
    # Funktionen har parameterna lista, low och high
    # Returnerar en lista med alla element i lista som har
    # värden mellan low till high.
    def between(lista, low, high):
        result = []                # en tom lista
        for x in lista:            # loopa genom alla element x i lista
            if low <= x <= high: # Om elementet x har värde mellan low-high
                result.append(x)   # lägg till x till listan result
        return result              # Efter loopen: returnera listan result
    
    # Anrop...
    l = [3, 1, 8, 19, 2, 5, 12]
    print(between(l, 3, 12))		# Skriver [3, 8, 5, 12]
    
    

Exempel: Värld med irrande paddor

I stället för två paddor som i föregående lektion kan vi ha en lista med flera vimsiga paddor. Med användning av metoderna random_turtle och move_random från föregående lektion:
# Create a list of dizzy turtles turtles = [] # Listan är tom initialt for t in range(6): # En sex varvs loop # Skapa en padda i en slumpmässig position med random_turtle() turtles.append(random_turtle()) # Lägg paddan i listan # Nu finns sex paddor i listan # Notera: Här nedan har vi en dubbelloop, dvs en loop i en loop. # För varje varv i den yttre loopen, itereras den inre loopen. for i in range(1, 200): # Iterera 200 varv for t in turtles: # I varje varv iterera genom listan move_random(t) # Flytta resp padda slumpmässigt

Du kan se hela programmet här. Ladda gärna ner och prova!

Övning

  1. bild1

    Skapa en lista med 4 paddor som utplaceras i hörnen på en kvadrat. Rikta den första mot den andra, den andra mot den tredje, den tredje mot den fjärde och den fjärde mot den första. Så här:

    bild2

    Låt sedan paddorna gå ett steg (längd 5) mot den padda den är riktad mot. Uppdatera riktningarna så att de tittar mot sin målpaddas nya position. Så här kan det se ut efter en stund:

    Avbryt körningen när de möts i mitten.

    Lösningsförslag

    # Skapa fyra paddor, en i varje hörn. Lägg dem i en lista
    # De skall ha ritningen 270, 0, 90 resp 180 grader
    ts = [create_turtle(-200, 200, 270),
          create_turtle(-200, -200, 0),
          create_turtle(200, -200, 90),
          create_turtle(200, 200, 180)]
    
    # Så länge som avståndet mellan de två första är > 10
    while ts[0].distance(ts[1]) > 10:
        # För varje padda...
        for t in ts:
            t.forward(5) # Flytta den 5 pixlar
        
        # För varje padda...
        for i in range(4):
            j = (i + 1) % 4    # index för "nästa" padda
    		# Rikta paddan mot nästa paddas position
            ts[i].setheading(ts[i].towards(ts[j]))
    

    En program med hjälpfunktionen create_turtle finns här.

Dellistor — "skivning"

Med hjälp av kolon kan man skapa dellistor. Detta kallas på engelska för "slicing".
SkivaBetydelse
lst[m:n] Delen av listan lst som har index från m till n - 1.
lst[:] En ny lista med samma element som lst.
lst[m:] Lista med alla element från och med index m.
lst[:m] Alla element från början till och med element med index m-1.
lst[m:n:2] Delen av listan lst som har index från m till n - 1, varannat element
lst[m:n:s] Delen av listan lst som har index från m till n - 1, var s:te element
lst[m:n:-1] Delen av listan lst som har index från m till n - 1, i bakvänd ordning. Notera m > n.

Exempel

Antag att listan lst = [10, 11, 12, 13, 14, 15]

KodVärde
lst[2:5] [12, 13, 14]
lst[:2] [10, 11]
lst[2:2] []
lst[:] [10, 11, 12, 13, 14, 15]
lst[-3:] [13, 14, 15]
lst[-3:10] [13, 14, 15]
lst[-100:2][10, 11]

Som synes går det bra att använda index-värden utanför gränserna i kolonuttrycken.

Det går också att ändra i listan både med tilldelningsoperatorn och med del-satsen

KodListans värde efteråt
lst [10, 11, 12, 13, 14, 15]
lst[1:3] = [21, 22, 23] [10, 21, 22, 23, 13, 14, 15]
del lst[2:4] [10, 21, 13, 14, 15]
lst[:2] = [] [13, 14, 15]
Här finns fler exempel på skivning.

Övningar

  1. Skriv en funktion smooth(x) som tar emot en lista med tal. Funktionen ska skapa och returnera en ny lista med samma antal element. Elementen på första och sista plats ska vara samma som i x medan element på plats i ska vara medelvärdet av av x[i-1], x[i] och x[i+1].

    Exempel:

     print(smooth([1, 2, 6, 4, 5, 0]))

    ska ge utskriften

     [1, 3.0, 4.0, 5.0, 3.0, 0]

    Lösningsförslag
    def smooth(a):
        res = []           # Börja med en tom lista res
        res.append(a[0])   # Lägg till a's första element
    	# Iterera genom övriga element i a
        for i in range(1, len(a)-1):
            # Lägg dit summan av elementen i en skiva av a
            res.append(sum(a[i-1:i+2])/3)
        # Slutligen, lägg till a's sista element
        res.append(a[-1])
        return res
    

Metoder och operatorer som ger information om listor

Uttryck Värde Kommentar
a = [3, 9, 2, 7, 9, 2, 3]
a.count(9) 2
a.count('a') 0
a.index(7) 3
a.index(9) 1
a.index(9, 3) 4 Börjar leta i position 3.
3 in a True
'x' in a False
'x' not in a True
a = [[1, 1], 1, [1, 2], [1, 1]] Innehåller fyra element: [1, 1], 1, [1, 2], [1, 1]
a.count(1) 1 Räknar bara på "topp"-nivå, dvs nivå 1 .
a.count([1, 1]) 2 Räknar bara på nivå 2.
a.index([1, 2]) 2 Räknar bara på nivå 1.

Övningar

  1. Skriv en funktion counter2(x, lista) som räknar hur många gånger värdet x förekommer på nivå 2 i listan lista. Elementen i lista kan förutsättas vara listor.

    Exempel: counter2(1, [[[1, 1]], [1, 2, 1], [1, 2]]) ska returnera 3 dvs den ska inte räkna ettorna i listans första element eftersom dessa finns i en sublista.

    Lösningsförslag
    def counter2(x, lista):
        res = 0
        for lst in lista:        # Iterera för varje element lst
            res += lst.count(x)  # lst.count(x) räknar antal x i listan lst
        return res
    
  2. Ovanstående funktion förutsatte att elementen i listan är listor. Vad händer om de inte är det? Prova!
  3. Med hjälp av standardfunktionen type kan man undersöka typen av ett visst värde. Exempelvis har uttrycket type(42) == int värdet True, type(42) == list värdet False och type(['a', 1, [2, 3]]) == list värdet True.

    Skriv funktionen counter(x, lista) som räknar förekomsten x på både nivå 1 och 2.

    Exempel: counter(1, [[[1, 1]], [1, 2, 1], 1, [1, 2], 1]) ska returnera 5.

    Lösningsförslag
    def counter(x, lista):
        res = 0
        for lst in lista:           #Iterera för varje element lst
            if type(lst) == list:   #Om elementet är av typen list?
                res += lst.count(x) #Räkna antal x i listan lst
            elif lst == x:          #Annars om lst är x
                res += 1
        return res
    

Metoder som ändrar listor

Vi har tidigare sett dels hur enskilda list-element kan ändras med tilldelningsoperatorn (typ a[3]='hej') och hur element kan läggas till på slutet med metoden append. Det finns flera andra metoder som kan förändra en list.
KodListans nya innehållKommentar
a = [21, 11, 42, 17]
a.extend([0, 3]) [21, 11, 42, 17, 0, 3]
a.pop() [21, 11, 42, 17, 0] pop returnerar 3.
a.pop(1) [21, 42, 17, 0] pop returnerar 11.
a.insert(2, 47) [21, 42, 47, 17, 0]
a.append(47) [21, 42, 47, 17, 0, 47]
a.remove(47) [21, 42, 17, 0, 47]
a.reverse() [47, 0, 17, 42, 21]
a.sort() [0, 17, 21, 42, 47]
a.clear() []
a = ['Ola', 'Bo', 'Mi'] ['Ola', 'Bo', 'Mi']
a.sort() ['Bo', 'Mi', 'Ola']
a.append(3) ['Bo', 'Mi', 'Ola', 3]
a.sort() TypeError: '<' not supported
between instances of 'int' and 'str'
Elementen måste vara jämförbara.
a = [[2, 2, 1], [2, 1], [2, 3]] [[2, 2, 1], [2, 1], [2, 3]]
a.sort() [[2, 1], [2, 2, 1], [2, 3]] Listelement är jämförbara

Övningar

  1. Skapa en lista my_list med 10 slumpade heltal i intervallet [0, 10]. Skriv sedan koden som tar bort största värdet ur listan. Om det värdet finns två gånger, ta bort det ena. Redogör för (minst) 2 olika sätt det kan göras på. Lösningsförslag
    # Skapa en lista med 10 slumpade tal:
    my_list = []
    for i in range(10):
        my_list.append(random.randint(0, 10))
       
    # Ta bort största talet, alternativ 1:
    my_list.remove(max(my_list))   
    print('Listan med största elementet borttaget: ',my_list)
    
    # Ta bort största talet, alternativ 2:
    my_list.sort() # ELLER my_list = sorted(my_list)
    my_list.pop()
    print('Listan sorterad med största elementet borttaget: ',my_list)
    
  2. Antag att lista = ['a', 'b', 'c']. Vad blir resultatet av lista.append([1, 2]) och lista.extend([1, 2])? Lösningsförslag
    Prova!
  3. Skriv en funktion extend(lista, x) som gör samma sak som lista.extend(x) gör utan att använda metoden extend. Förutsätt att x är en lista. Lösningsförslag
    def extend(lista, x):
        # Iterera för varje element z från listan x
        for z in x:  
            lista.append(z) # Lägg till resp element z till lista 
    
  4. Metoden remove tar bort första förekomsten av värdet x på översta nivån. Skriv en funktion remove_all(lista, x) som tar bort alla förekomster av x på översta nivån i listan lista. Lösningsförslag
    def remove_all(lista, x):
        # Så länge som värdet x finns som element i lista
        while x in lista:
            lista.remove(x) # Tag bort elementet med värdet x
    				
    
    Anmärkning: Eftersom anropet lista.remove(x) börjar leta från början varje gång så är detta en långsam metod för långa listor.

Ett annat sätt att skapa listor är med list comprehension (listbyggare)

En vanlig situation är att man vill bygga upp en ny lista utifrån en gammal listaOld. I flera tidigare och exempel och övningar har vi sett mönstret
lista = [] for elem in listaOld: if elem uppfyller någon egenskap: lista.append[elem]

Detta mönster hade vi senast i lösningen till övning 4 ovan där vi också påpekade att den givna lösningen var ineffektiv för långa listor.

Det finns ett sätt som är både enklare och effektivare! För att göra en ny lista som innehåller alla element från en lista utom de med värdet x kan vi skriva:

nylista = [e for e in lista if e != x]
Detta är mycket effektivare eftersom vi bara går igenom listan en gång. En skillnad mot funktionen remove_all(lista, x) i övning 4 är att vi gör en ny lista i stället för att ändra i den gamla. För att få samma effekt som anropet remove_all(lista, x) får vi alltså skriva
lista = [e for e in lista if e != x]
I högerledet byggs en lista upp (skapas) mellan klamrarna [e ... ]genom att iterera igenom alla element e i variabeln lista.
Iterationen styrs med: for e in lista
I varje iteration: Om elementet e i listan ej är x lägg till elementet i den lista som skapas
Styrs med if-satsen: if e != x
Variabeln lista (i vänsterledet) tilldelas värdet av den skapade listan. Variabeln lista ändras därmed.
(Ovan sats fungerar ej som kropp för remove_all(lista, x), ty lista får ny referens. Metoden remove_all(lista, x) måste returnera lista)

Denna konstruktion kallas för "list comprehension" på engelska. Vi kommer använda termen listbyggare på svenska.

Fler exempel:

Uttryck Värde
a = [x for x in range(7)] [0, 1, 2, 3, 4, 5, 6]
[z*z for z in a] [0, 1, 4, 9, 16, 25, 36]
[z*z for z in a if z%2==0] [0, 4, 16, 36]
[round(z/3,2) for z in a] [0.0, 0.33, 0.67, 1.0, 1.33, 1.67, 2.0]

Tupler

Tupler är likt listor men de är "immutable" dvs går inte att ändra. Tupler skrivs med vanliga parenteser i stället för med hakparenteser. För övrigt använder man index-operatorn på samma sätt. Exempel:
KodVärdeKommentar
t = (10, 11, 12, 13)
t[-1]13Indexering som i listor.
t[0:3](10, 11, 12)Skivning som i listor.
t.index(12)2Index för första förekomst.
(42) 42Ingen tupel! Vanligt int.
(42,)(42,)Tupel med ett element måste skrivas med kommatecken.
()()Tupel med noll element.
t[-1] = 4213Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment
'x', 'a', 'y'('x', 'a', 'y')Kan (ibland) skrivas utan parenteser. Se return-satsen från lösningen av andragradsekvationen, nätlektion 4 "Funktioner med flera returvärden"!
sorted(t, reverse=True)13, 12, 11, 10Standardfunktioner går bra. Funktionen returnerar en tupel

Eftersom tupler är oföränderliga fungerar bara ett fåtal av listornas metoder: copy, count och index.

Man kan tycka att tupler inte tillför något utöver vad listor ger (allt som man kan göra med tupler kan man också göra med listor men inte tvärt om). Motiveringen till deras existens är att hanteringen av dem kräver mindre resurser än vad listor gör. Det kommer exempel på användning av tupler i kommande lektioner.

Nu följer de obligatoriska uppgifterna som skall redovisas, nämligen deluppgift 1a, 1b, 1c, 2 och 3

Notera att den pythonkod du redovisar skall följa kodningsreglerna

    1. Skriv en funktion delete(my_list, number) som fungerar som metoden remove. Funktionen ska ta en lista och ett heltal som parametrar. Om heltalet finns i listan ska det tas bort. Om heltalet finns i listan flera gånger räcker det med att funktionen tar bort ett av dem.
      Du får använda metoder i list-klassen men inte metoden remove.
      Funktionen ska inte returnera något värde, dvs skall ej innehålla någon return-sats.

      Testa din funktion delete så här:

      • Skapa en lista och fyll den med slumpade heltal i intervallet [0,10]. Tips: random.randint(0,10) returnerar ett heltal [0,10]
      • Slumpa ett heltal i samma intervall och spara i en variabel.
      • Anropa funktionen delete med din lista och det slumpade heltalet.
      • Skriv ut listan så du ser att funktionen tagit bort talet, om det fanns i listan från början.
      Koden i den pythonfil du skapar bör i princip vara uppbyggd så här:
      import ...
      	
      # Definition av funktionen delete
      def delete(my_list, number):
          ...  # Funktionens kropp
      	
      # Här följer anrop (test) a funktionen delete
      	
      # Skapa en lista och fyll den med slumptal 0-10
      ...
      	
      # Slumpa ett heltal 0-10
      ...
      	
      # Anropa funktionen delete
      # Notera att anropet antyder att funktionen ej returnerar något
      # ty annars bör det exvis ha stått: ... =  delete(...)
      delete(...)
      	
      # Skriv ut listan
      print(...)
      	

      När ovan fungerar, gå vidare med b)

    2. Lägg till kod (sist i filen) som tömmer listan enligt följande.
      Upprepa tills listan är tom:
      • slumpa ett tal i intervallet [0, 10].
      • anropa funktionen delete med listan och det slumpade talet
      Skriv ut hur många iterationer det tog innan listan var tom.

      När ovan fungerar, gå vidare med c)

    3. Här ser du ett (felaktigt) förslag till funktionen delete. Testa koden. Förklara i ord varför talet 7 fortfarande finns kvar i my_list vid sista utskriften.

      def delete(the_list, number):
            new_list = []        # Den nya listan sätts tom, initialt.
            for n in the_list:   # För varje element n i listan...
                if n == number:  # Om elementet är lika med number...
                    continue     # Hoppa över resterande satser i detta loopvarv.
                new_list.append(n) # Annars, lägg till elementet i den nya listan
            the_list = new_list
            print('listan i delete', the_list) 
      
      # Anropande kod
      my_list = [2, 5, 1, 7, 12, 0, -5]
      print('my_list före delete', my_list)
      delete(my_list, 7)
      print('my_list efter delete', my_list) # har 7 tagits bort från listan?
      
      
      Tips: se Föreläsning 4, rubriken "Skriva egna funktioner för listor, lista som parameter. Och minilektionen "Debugging i Thonny" rubriken "Funktioner med lista som parameter".

  1. Skriv funktionen smooth_a(x, n) som tar emot en lista x med tal och ett icke-negativt heltal n. Funktionen ska skapa och returnera en ny lista r där

    ri = (xi-n + xi-n-1 + xi-n-2 + ... + xi-1 + xi + xi+1 + ... + xi+n-1 + xi+n) / (2*n + 1)

    dvs medelvärdet av xi och de 2n omkringliggande talen.

    Om n = 1 blir resultatet som i övningen ovan, åtminstone i de inre punkterna.

    Notera hur funktionen hanterar punkterna som ligger nära kanterna hanteras, dvs när intervallet [i-n:i+n] är utanför listan: bredden (2n+1) på utjämningsoperatorn ska användas men i punkterna som får index mindre än 0 ska det första värdet användas och i punkter som får index efter sista elementet ska sista elementet användas. Man kan se det som att listan utvidgas både uppåt och nedåt med n element som sätts lika med randelementet.

    Exempel: Koden

    x = [1, 2, 6, 4, 5, 0, 1, 2] print('smooth_a(x, 1): ', smooth_a(x, 1)) print('smooth_a(x, 2): ', smooth_a(x, 2))
    ska ge följande utskrifter
    smooth_a(x, 1): [1.3333333333333333, 3.0, 4.0, 5.0, 3.0, 2.0, 1.0, 1.6666666666666667] smooth_a(x, 2): [2.2, 2.8, 3.6, 3.4, 3.2, 2.4, 2.0, 1.4]

    Notera att funktionen smooth_a(x, n) inte får ändra elementens värden i listan x. Du kan testa detta genom att skriva ut listan x efter varje anrop av funktionen smooth_a(x, n).

  2. Skriv funktionen round_list(a_list, ndigits) som returnerar en ny lista av talen i a_list men där talen är avrundade till ndigits decimaler.
    Exempel: Koden
    print('smooth_a(x, 1) rounded: ', round_list(smooth_a(x, 1), 2))
    ska, med samma värde på x som ovan, ge utskriften
    smooth_a(x, 1) rounded: [1.33, 3.0, 4.0, 5.0, 3.0, 2.0, 1.0, 1.67]
    Du måste använda "list comprehension" för att lösa, åtminstone för någon del av uppgiften.
    Försök använda list-operatorer, skivningar och listmetoder så mycket som möjligt!
    Tips för avrundningen: Använd pythons inbyggda funktion round.

    Frivillig uppgift

  3. Skriv funktionen smooth_b(x, n) som, precis som smooth_a, tar emot en lista x med tal och ett icke-negativt heltal n. Funktionen ska, precis som smooth_a skapa och returnera en ny lista r där

    ri = (xi-n + xi-n-1 + xi-n-2 + ... + xi-1 + xi + xi+1 + ... + xi+n-1 + xi+n) / (2*n + 1)

    dvs medelvärdet av xi och de 2n omkringliggande talen.

    Om n = 1 blir resultatet som i övningen ovan, åtminstone i de inre punkterna.

    Skillnaden mellan de båda funktionerna är hur punkterna som ligger nära kanterna hanteras, dvs när intervallet [i-n:i+n] är utanför listan. Följande strategi skall implementeras för smooth_b(x, n):
    1. smooth_b(x, n): Bara punkter som finns i listan ska användas så medelvärdet bildas då över färre punkter.

    Exempel: Koden

    x = [1, 2, 6, 4, 5, 0, 1, 2] print('smooth_b(x, 1): ', smooth_b(x, 1)) print('smooth_b(x, 2): ', smooth_b(x, 2))
    ska ge följande utskrifter
    smooth_b(x, 1): [1.5, 3.0, 4.0, 5.0, 3.0, 2.0, 1.0, 1.5] smooth_b(x, 2): [3.0, 3.25, 3.6, 3.4, 3.2, 2.4, 2.0, 1.0]

    Notera att funktionen smooth_b(x, n) inte får ändra elementens värden i listan x. Du kan testa detta genom att skriva ut listan x efter varje anrop av funktionerna smooth_b(x, n).

Fråga

Hur många timmar har du arbetat med denna lektion?


Gå till nästa lektion eller gå tillbaka