qr code

Listor med Python

Listor med Python

En kortare lista i Python kan skapas genom att listelement skrivs innanför hakparenteser åtskilda av kommatecken.

Koden:

kvadrater = [1, 4, 9, 16, 25]
bokstäver = ['a', 'b', 'c']
print(kvadrater)
print(bokstäver)

ger utskriften:

[1, 4, 9, 16, 25]
['a', 'b', 'c']

Elementen i en lista med \(n\) stycken element är numrerade med index från \(0\) till \(n-1\). Du kommer åt ett element i en lista genom att ange listans namn följt av elementets index mellan hakparenteser.

Koden:

kvadrater = [1, 4, 9, 16, 25]
bokstäver = ['a', 'b', 'c']
print(kvadrater[0])
print(bokstäver[2])

ger utskriften:

1
c

Om du anger ett index utanför listan får det ett fel vid körningen (ett exekveringsfel), exempelvis hade koden print(bokstäver[3]) gett ett exekveringsfel.

Funktionen len()

Funktionen len(<lista>) returnerar hur många element den lista innehåller som anges som argument. Funktionen kan också användas på en textsträng och returnerar då antalet tecken i textsträngen.

Koden:

kvadrater = [1, 4, 9, 16, 25]
land = "Sverige"
print("Den finns", len(kvadrater), "kvadrater i listan.")
print(land, "innehåller", len(land), "bokstäver.")
print("Den sista kvadraten är", kvadrater[len(kvadrater)-1])

ger utskriften:

Den finns 5 kvadrater i listan.
Sverige innehåller 7 bokstäver.
Den sista kvadraten är 25

Det sista index i listan kvadrater har index len(kvadrater)-1 vilket gör att koden kvadrater[len(kvadrater)-1] ger oss det sista elementet i listan. Denna konstruktion för att komma åt det sista listelementet återfinns i många programmeringsspråk. I Python kan man göra det på ett fiffigare sätt genom att använda negativa index.

Negativa index

Om du anger ett negativt index till en lista räknas det från slutet. Index -1 är det första elementet från slutet, index -2 är det andra elementet från slutet, osv.

Koden:

kvadrater = [1, 4, 9, 16, 25]
print("Den sista kvadraten är", kvadrater[-1])

ger utskriften:

Den sista kvadraten är 25

Dellistor (slice)

Du kan komma åt en del av en lista genom att använda operatorn : när du anger en listas index. Du skapar på detta vis en del av en lista eller en slice (på engelska).

Om vi utgår ifrån listan kvadrater, så kan du skapa dellistor på tre olika sätt.

  • kvadrater[i:] gör en dellista som och har med alla element fr.o.m. index i till slutet av listan.
  • kvadrater[i:j] gör en dellista som har med alla element fr.o.m. index i till index j. Elementet med index j inkluderas inte.
  • kvadrater[:j] gör en dellista som har med alla element från början av listan till index j. Elementet med index j inkluderas inte.

Koden:

kvadrater = [1, 4, 9, 16, 25]
print(kvadrater[3:])
print(kvadrater[1:3])
print(kvadrater[:3])
print(kvadrater[1:-1])

ger utskriften:

[16, 25]
[4, 9]
[1, 4, 9]
[4, 9, 16]

Det sista anropet av print() gör en dellista av alla element utom det första och det sista.

Operatorn : kan även användas på textsträngar. Koden

land = "Sverige"
print(land[:2])
print(land[2:5])
print(land[5:])

ger utskriften

Sv
eri
ge

Listmetoder

Det finns ett antal inbyggda metoder på listor som skrivs med punktnotation efter en listas namn. Några sådana metoder visas här på listan lst

metod förklaring
lst.append(x) lägg till x sist i listan
lst.remove(x) ta bort den första förekomsten av x
lst.index(x) returnera index av den första förekomsten av x
lst.insert(k, x) lägg till x på plats k i listan
lst.clear() ta bort alla element
lst.reverse() vänd på ordningen till omvänd ordning

Koden:

kvadrater = [1, 4, 9, 16, 25]
kvadrater.reverse()
print(kvadrater)
länder = ["Sverige", "Danmark", "Norge"]
print(länder)
print("Danmark har index", länder.index("Danmark"))
länder.append("Finland")
print(länder)

ger utskriften:

[25, 16, 9, 4, 1]
['Sverige', 'Danmark', 'Norge']
Danmark har index 1
['Sverige', 'Danmark', 'Norge', 'Finland']

För fler listmetoder se Python: More on lists.

Addera listor

Om du har två listor kan du skapa en tredje list genom att addera de två listorna. Koden:

lst1 = ["Sverige", "Danmark", "Norge"]
lst2 = ["Finland", "Island"]
lst3 = lst1 + lst2
print(lst3)

ger utskriften:

['Sverige', 'Danmark', 'Norge', 'Finland', 'Island']

Du kan addera listor även om de innehåller element av olika datatyp. Följande kod:

lst1 = ["Sverige", "Danmark", "Norge"]
lst2 = [17, -9, 2]
lst3 = lst1 + lst2
print(lst3)

ger utskriften:

['Sverige', 'Danmark', 'Norge', 17, -9, 2]

Operatorn in

Operatorn in som används tillsammans med funktionen range() i en for-sats kan också användas för att kontrollera om ett element tillhör en lista.

Koden:

lst = [9, 5, 2]
print(3 in lst)
print(5 in lst)

ger utskriften:

False
True

Operatorn in kan användas i en for-sats för att iterera över alla element i en lista.

Koden:

lst = [9, 5, 2]
for tal in lst:
  print(tal)

ger utskriften:

9
5
2

Operatorn in kan också användas i en for-sats för att iterera över alla bokstäver i en textsträng.

Koden:

str = "Hej"
for bokstav in str:
  print(bokstav)

ger utskriften:

H
e
j

Skapa listor

Om du vill skapa en lista genom att iterera, kan du börja med att skapa en tom lista och sedan lägga till ett element i taget i en loop. Exempelvis kan listan [2, 7, 12, 17, 22] skapas med följande kod:

lst = []
for i in range(5):
  lst.append(2+5*i)
print(lst)

Med Python finns det ett smartare sätt att skapa listor med loopar, så kallad list comprehension. För att skapa samma lista med list comprehension, skriver du följande kod:

lst = [2+5*i for i in range(5)]
print(lst)

Du kan använda list comprehension för att skapa en lista av bokstäver som är tagna ur en textsträng. Koden:

namn = "Sverige"
lst = [bokstav for bokstav in namn]
print(lst)

ger utskriften:

['S', 'v', 'e', 'r', 'i', 'g', 'e']
Exempel 1

Testkör koden:

lst = [i for i in range(100)]
print(lst, sep=" ")

Du ska nu ta bort alla tal från listan som är delbara med fem. Lägg till följande kod:

for tal in lst:
  if tal%5 == 0:
    lst.remove(tal)

och skriv ut resultatet.

Det går också att använda list comprehension för att skapa en lista med element ur en annan lista om något villkor är uppfyllt. Villkoret fungerar som ett filter för vilka element som ska tillåtas. Vi kan exempelvis skapa en lista med alla tal mindre än 100 som inte är delbara med fem, med följande kod:

lst = [i for i in range(100) if i%5 != 0]
print(lst, sep=" ")
list comprehension

kan användas med eller utan "filtrering".

ny_lista = [<uttryck(i)> for i in gammal_lista]
ny_lista = [<uttryck(i)> for i in gammal_lista if <filtrering(i)>]

Variabelnamnet i kan bytas mot andra variabelnamn.

Funktionen join()

Om du har en lista där varje listelement är en textsträng, kan du med funktionen <separation>.join(<lista>) sätta samman alla listelement till en enda textsträng där de enskilda textsträngarna separeras av någon textsträng som du anger. Funktionsanropet ska föregås av den text som ska separera listelementen, följt av en punkt.

Koden:

namn = ["Sverige", "Danmark", "Norge"]
länder1 = "-".join(namn)
länder2 = "".join(namn)
print(länder1)
print(länder2)

ger utskriften:

Sverige-Danmark-Norge
SverigeDanmarkNorge

Om du vill göra en textsträng av en lista innehållande tal, kan du använda omvandla talen till textsträngar först. Följande kod:

tallista = [5, 7, 3]
text1 = "-".join(str(tal) for tal in tallista)
text2 = "".join(str(tal) for tal in tallista)
print(text1)
print(text2)

ger utskriften:

5-7-3
573

Funktionen split()

Med funktionen <textsträng>.split(<separation>) kan du dela upp en textsträng i delar som läggs in en lista. Om du inte anger något argument till split() separeras textsträngen av blanktecken.

Med följande kod separeras textsträngarna av kommatecken respektive blanktecken:

text1 = "Sverige, Danmark, Norge"
text2 = "Island Finland"
lst1 = text1.split(",")
lst2 = text2.split()
print(lst1)
print(lst2)

Utskriften blir:

['Sverige', ' Danmark', ' Norge']
['Island', 'Finland']

Om du vill dela upp en textsträng av tal som är separerade på något vis, till en lista av tal, kan du använda följande kod som konverterar varje element till heltal respektive flyttal:

heltal = "6,9,14"
lst1 = [int(tal) for tal in heltal.split(",")]
print(lst1)
flyttal = "3.14 2.5 -9.7"
lst2 = [float(tal) for tal in flyttal.split()]
print(lst2)

Utskriften blir:

[6, 9, 14]
[3.14, 2.5, -9.7]

Kopiera listor

Om du försöker göra en kopia av en lista med en enkel tilldelning, kommer koden att bete sig på ett till synes märkligt sätt. Med följande kod kopieras en lista med en tilldelning. Därefter förändras ett element i den ursprungliga listan. Då kommer motsvarande element i kopian också att förändras.

lst1 = [2+5*i for i in range(4)]
lst2 = lst1
print("lst1 = ", lst1)
print("lst2 = ", lst2)
lst1[2] = -5
print("lst1 = ", lst1)
print("lst2 = ", lst2)

Utskriften blir:

lst1 =  [2, 7, 12, 17]
lst2 =  [2, 7, 12, 17]
lst1 =  [2, 7, -5, 17]
lst2 =  [2, 7, -5, 17]

För att förstå detta beteende kan man tänka sig att en lista refererar till ett antal minnesceller där elementen lagras.

listor refererar till minnesceller

När lst2 tilldelas lst1, kommer båda listorna att referera till samma sjok minnesceller, det skapas inte en lagring i nya minnesceller.

Om du vill skapa en kopia av en lista så att det skapas en ny lagring, så att varje element kopieras till ett nytt element i den nya listan, kan du använda funktionen <lista>.copy().

Med koden

lst1 = [2+5*i for i in range(4)]
lst2 = lst1.copy()
print("lst1 = ", lst1)
print("lst2 = ", lst2)
lst1[2] = -5
print("lst1 = ", lst1)
print("lst2 = ", lst2)

blir utskriften:

lst1 =  [2, 7, 12, 17]
lst2 =  [2, 7, 12, 17]
lst1 =  [2, 7, -5, 17]
lst2 =  [2, 7, 12, 17]

Slumpad ordning

I modulen random finns det en funktion shuffle() som ser till att elementen i en lista ordnas i en slumpad ordning, på ett sätt som liknar hur man kan blanda korten i en kortlek.

För att kunna använda shuffle() måste du först importera den från random.

Med följande kod

from random import shuffle

lst = [2*i for i in range(6)]
print(lst)
shuffle(lst)
print(lst)

blir utskriften exempelvis

[0, 2, 4, 6, 8, 10]
[4, 10, 2, 0, 6, 8]

där den sista raden i utskriften visar en slumpvis ordning som kan variera varje gång programmet körs.

Programmeringsuppgifter

Uppgift 1

Lista av namn

Gör en lista med ett antal valfria namn.

  1. Låt användaren skriva in ett namn och skriv sedan ut huruvida namnet finns med i listan eller inte.
  2. Ändra i koden så att användaren kan ta bort ett namn ur listan. Om det namn som användaren skriver in finns med i listan, ska namnet tas bort, därefter ska listan skrivas ut. Annars ska ett valfritt meddelande skrivas ut.
  3. Ändra i koden så att användaren kan lägga till ett namn i listan. Skriv sedan ut listans innehåll och hur många namn det finns i listan.

Uppgift 2

Skapa listor

Använd list comprehension för att skapa följande tre listor:

  • [6, 10, 14, 18, 22]
  • [9, 4, -1, -6]
  • [-1.5, -1.7, -1.9, -2.1, -2.3, -2.5]

Uppgift 3

Ta reda på filändelse

Gör ett program som låter användaren skriva in ett filnamn inklusive filändelsen. Ett sådant filnamn kan exempelvis vara "uppsats.docx" (en Word-fil), "bild.png" eller "test.min.js" (en minifierad Javascript-fil).

Ditt program ska sedan skriva ut filändelsen. Använd funktionen split().

En körning kan exempelvis se ut så här

Skriv in ett filnamn: uppsats.docx
Filändelsen: docx

eller så här

Skriv in ett filnamn: test.min.js
Filändelsen: js

Uppgift 4

Hantera personnummer

Låt användaren mata in ett personnummer på formen

ååååmmdd-xxxx

Använd operatorn : (slice) för att skriva ut år, månad, dag samt de fyra sista siffrorna.

En körning kan se ut så här:

Skriv in personnummer: 20030724-3907
år: 2003
månad: 07
dag: 24
fyra sista: 3907

Uppgift 5

Skapa lista från inmatning

Använd funktionen split() för följande övningar.

  1. Låt användaren mata in ett antal namn separerade av blanktecken. Lägg in namnen i en lista och skriv ut listan. En körning kan se ut så här:

    Skriv in namn: Kurt Ellen Pia Sture
    ['Kurt', 'Ellen', 'Pia', 'Sture']
  2. Låt användaren mata ett antal heltal separerade av blanktecken. Lägg in talen i lista av heltal. Skriv först ut listan. Sortera sedan listan och skriv ut den sorterade listan. En körning kan se ut så här:

    Skriv in heltal: -7 13 0 8 -3
    [-7, 13, 0, 8, -3]
    [-7, -3, 0, 8, 13]

Uppgift 6

Beräkna medelvärde

Låt användaren skriva in ett antal decimaltal separerade av blanktecken. Lägg in talen i en lista av flyttal.

Observera att decimalpunkt ska användas när du skriver in talen som användare.

Definiera en funktion som tar emot en lista som argument och returnerar medelvärdet av talen i listan. Använd funktionen på de tal användaren matat in och skriv ut medelvärdet.

En körning kan se ut så här:

Skriv in decimaltal: 3.5 8.8 13 7.2 6.5
medelvärdet = 7.8

Uppgift 7

Beräkna median

Låt användaren skriva in ett antal decimaltal separerade av blanktecken. Lägg in talen i en lista av flyttal.

Definiera en funktion som tar emot en lista som argument och returnerar medianen av talen i listan. Skilj på de två fallen att listan innehåller ett udda antal tal och ett jämnt antal, så att medianen alltid beräknas korrekt. Använd funktionen på de tal användaren matat in och skriv ut medianen.

En körning kan se ut så här:

Skriv in decimaltal: 3.5 8.8 13 7.2 6.5
medianen = 7.2

Med ett jämnt antal decimaltal kan det se ut så här:

Skriv in decimaltal: 3.5 8.8 13 7.2
medianen = 8.0

Uppgift 8

Öva på sjuans tabell

Gör ett program som låter användaren öva på sjuans tabell (multiplikationstabell). Programmet ska fråga vad sju multiplicerat med \(x\) är för varje heltal \(1\le x \le 10\) men i slumpvis ordning. Använd en lista och funktionen shuffle() från modulen random. Skriv om svaret var rätt eller fel efter varje fråga. Ge en poäng för varje korrekt svar och skriv ut den totala poängen när användaren besvarat de tio frågorna.

Uppgift 9

Slumpa gruppindelning

Gör en lista av namn. Namnen kan exempelvis vara eleverna i en klass.

Definiera en funktion gör_grupper(elever, storlek) som har två parametrar, en lista elever och ett tal storlek som representerar hur många det maximalt ska var i varje grupp.

Funktionen gör_grupper ska börja med att skriva ut hur många elever det är och den maximala gruppstorleken. Därefter ska elevernas ordning slumpas och en elev per rad ska skrivas ut i en loop. Se först till att denna kod fungerar.

Om gruppstorleken är tre ska var tredje rad i utskriften av eleverna föregås av ett gruppnummer, om gruppstorleken är fyra ska detta hända på var fjärde rad, osv. Lägg till en if-sats överst i loopen som skriver ut gruppnummer. Använd resten och kvoten vid heltalsdivision för att skriva villkoret i if-satsen och ett uttryck för gruppnumret.

Anropa funktionen gör_grupper med din lista som första argument och valfri gruppstorlek som andra argument.

En körning kan exempelvis se ut så här:

11 elever
Gruppstorlek max 3
------------
Grupp 1
    Mia
    My
    Kim
Grupp 2
    Alfons
    Olle
    August
Grupp 3
    Maja
    Oskar
    Alva
Grupp 4
    Lukas
    Elmer

Uppgift 10

Omvandla från decimalt till binärt

Denna uppgift är en mer avancerad variant av Uppgift 6 på sidan Loopar med Python: Programmeringsuppgifter.

Den algoritm som används för att omvandla från decimalt till binärt beskrivs på sidan Grundläggande datorkunskap: Exempel 4.

  • Låt användaren skriva in ett positivt heltal.
  • Använd upprepad heltalsdivision för att lagra siffrorna i det binära talet i en lista i omvänd ordning.
  • Byt ordning på listan så den blir rätt.
  • Omvandla elementen i listan till en textsträng och skriv ut textsträngen.

En körning kan se ut så här:

Använd upprepad heltals

Skriv in ett positivt heltal: 210
På binär form skrivs talet som: 11010010

Uppgift 11

Eratosthenes såll

Eratosthenes såll är en algoritm för att bestämma primtal. Algoritmen uppfanns i det antika Grekland och används än idag. Algoritmen fungerar så här för att bestämma alla primtal som är mindre än hundra:

Gör en lista med alla tal mellan 2 och 100.

Välj det första talet i listan (talet 2). Ta bort alla tal i listan efter denna position som är delbara med 2.

Eratosthenes1 Eratosthenes2

Välj det andra talet i listan (talet 3). Ta bort alla tal i listan efter denna position som är delbara med 3.

Eratosthenes3 Eratosthenes4

Välj det tredje talet i listan (talet 5). Ta bort alla tal i listan efter denna position som är delbara med 5.

Eratosthenes5 Eratosthenes6

Upprepa på detta vis tills du gått igenom talen i listan.

Implementera Eratosthenes såll i Python. Du kommer att behöva två nästlade loopar, den ena loopen ligger inuti den andra.

Du kommer att behöva två variabler för att stega dig fram, en variabel som håller reda på den position som är blåmarkerad i bilderna och en för den position som är rödmarkerad.

I den inre loopen kommer listan att bli kortare och den variabel som räknar fram längs de röda positionerna riskerar att hamna utanför den aktuella listans längd. När du kontrollerar delbarhet kan du därför börja med att kolla att det index du vill använda inte är utanför listan. Om variabeln pos används för den blå positionen och variabeln index för den röda, kan du använda följande if-sats:

if index < len(lst) and lst[index]%lst[pos] == 0:
	lst.remove(lst[index])

I en sådan if-sats med ett logiskt och, kontrolleras först det första villkoret. Om detta villkor är falskt utförs aldrig kontrollen av det andra villkoret. Med denna kod riskerar du aldrig att index används utanför listan.

Avsluta programmet med att skriva ut listan. Listan ska se ut så här:

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

När du fått din kod att fungera kan du testa att generera alla primtal mellan 2 och 1000. Det finns 168 sådana primtal.