Werken met lijsten
Inleiding
Lijsten (list
) in Python zijn een van de belangrijkste datatypes waarmee je als beginnend programmeur in aanraking zult komen. In Eerste stappen heb je er al kort kennis mee gemaakt. In dit hoofdstuk ga je dieper in op lijsten en leer je er verder mee werken.
Leerdoelen
Aan het einde van dit hoofdstuk:
-
Begrijp je wat een
list
is -
Begrijp je in welke situaties je lijsten toe kunt passen
-
Begrijp je hoe je met elementen in een
list
kunt werken
Lijsten: een inleiding
In deze paragraaf leer je wat een list
is, wat de specifieke kenmerken van lijsten zijn en hoe lijsten zich onderscheiden van andere collecties. Je leert ook in welke situaties je lijsten kunt gebruiken.
In de Eerste stappen leerde je al dat een list
een reeks is, en dat de volgende methodes beschikbaar zijn:
-
Controleren of een element zich in de reeks bevindt met
element in mijn_reeks
(ofnot in
). -
Reeksen bij elkaar voegen met
mijn_reeks + mijn_reeks
-
Reeksen vermenigvuldigen met
mijn_reeks * 3
-
Meerdere elementen ophalen op basis van index met
mijn_reeks[2:5]
(slicing) -
De lengte van de reeks bepalen met
len(mijn_reeks)
-
Het grootste element uit de reeks halen met
max(mijn_reeks)
-
Het kleinste element uit de reeks halen met
min(mijn_reeks)
-
De index ophalen van een element uit een reeks met
mijn_reeks.index(element)
-
Het aantal keer dat een element voorkomt in een reeks met
mijn_reeks.count(element)
Verderop leer je hoe je deze methodes toepast.
Een list
maken
Een list
kun je op verschillende manieren maken. Meestal zul je de vierkante haken gebruiken ([]
) of de ingebouwde functie list()
. Je kunt een list
leeg beginnen, maar ook direct items toevoegen:
# Lijsten maken
lege_lijst_1 = []
lege_lijst_2 = list()
lijst_met_items = [1, 2, 3, ]
Items in een list
scheidt je door een komma.
Komma’s
Je zult vaak zien dat er achter het laatste item van een
Print |
Kenmerken van lijsten
De belangrijkste kenmerken van een list
leerde je al in Eerste stappen:
-
Een
list
is een vorm van een reeks, ofwel een collectie elementen. -
Je haalt elementen op basis van een index op uit een
list
. -
De index begint bij 0, het eerste element haal je dus zo op:
mijn_lijst[0]
. -
Een
list
is muteerbaar (aanpasbaar). Je kunt elementen toevoegen, aanpassen en verwijderen. -
De elementen in een
list
hoeven niet van hetzelfde type te zijn.
Wanneer gebruik je een lijst?
Nu je weet wat de belangrijkste kenmerken van een list
zijn rijst de vraag: wanneer gebruik je een list
?
Aangezien een list
(meestal) meerdere elementen bevat, is het een logisch gegevenstype om te gebruiken op het moment dat je bepaalde handelingen op verschillende elementen wilt toepassen. Meestal zul je dit dan doen in een iteratie[1], bijvoorbeeld als je elke actieve gebruiker van je systeem een e-mail wilt sturen:
# Dummy code
for user in users:
# Mail elke user indien actief
if user.is_active:
send_mail(user)
Vaak gaat de afweging tussen een list
en tuple
. Beiden zijn reeksen met elementen waar je iets mee wilt doen. Maak je een collectie op basis van gegevens, dan valt de tuple
af, omdat deze niet-aanpasbaar is. Bijvoorbeeld:
# Collectie maken (list)
users = [] # Lege lijst
# Open een CSV bestand
with open("users.csv") as csvfile:
# Gebruik de csv module om het bestand in te lezen
csv_reader = csv.DictReader(csvfile)
# Voor elke regel in het CSV-bestand, haal de naam op uit de kolom
# "Name" en voeg dit toe aan de list users
for row in csv_reader:
users.append(row["Name"])
In bovenstaande (vereenvoudigd) voorbeeld lees je een CSV-bestand in, itereer je over elke rij en voeg je de naam die je in het CVS-bestand vindt toe aan de list
users
, die je op regel één hebt aangemaakt. Een resultaat ziet er als volgt uit:
print(users)
# ["Piet", "Marie", "Ali"]
Het geeft niet als je niet elke stap begrijpt, als maar duidelijk is dat je een list
opbouwt. In een for-loop
voeg je steeds een element toe aan een list
. Met een tuple
zal dit niet werken.
Je verkiest een tuple
boven een list
als de reeks niet zal wijzigen. Een tuple
verbruikt minder geheugen en is hierdoor efficiënter. Je ziet dit vaak met korte reeksen die binnen het programma worden rondgegeven, bijvoorbeeld de coördinaten van een plaats: (long, lat).
Werken met elementen in een lijst
In deze paragraaf leer je werken met de elementen in een list
: ophalen, aanpassen en verwijderen.
Elementen uit een lijst ophalen
Een veelvoorkomende handeling is het ophalen van één of meerdere elementen uit een list
.
Eén element ophalen
In hoofdstuk 1 in de paragraaf Collecties heb je al gezien hoe je een enkel element ophaalt uit een list
, op basis van de index:
eerste_item = lijst_met_items[0]
tweede_item = lijst_met_items[1]
Met de nul-gebaseerde indexering haal je het eerste element op met [0]
, het tweede element met [1]
, etc.
Indexering kan vanaf het begin van de list
, maar ook vanaf het einde. In plaats van positieve integers gebruik je dan negatieve integers. Het laatste element (dus het eerste gezien vanaf het eind) begint met index -1:
lijst_met_items = ["a", "b", "c", ]
laatste_item = lijst_met_items[-1] # "c"
Het een-na-laatste element haal je op met [-2]
, het twee-na-laatste element met [-3]
, etc. Waar indexering vanaf het begin nul-gebaseerd is, kun je indexering vanaf het einde beschouwen als een-gebaseerd (met een min-teken ervoor).
Element |
1 |
5 |
3 |
2 |
Plaats vanaf het eind |
4 |
3 |
2 |
1 |
Index |
-4 |
-3 |
-2 |
-1 |
Ophalen |
mijn_lijst[-4] |
mijn_lijst[-3] |
mijn_lijst[-2] |
mijn_lijst[-1] |
Slicen
Soms wil je niet één, maar meerdere elementen tegelijk ophalen uit een list
. Dit kan met slicen. De notatie hiervoor is [1:3]
.
mijn_lijst = [1, "b", "drie", 4, "V", ]
mijn_slice = mijn_lijst[1:3] # ["b", "drie"]
Het resultaat is een nieuwe list
. Let op dat de eerst index vanaf is en de tweede tot (en níet tot en met). Met [1:3]
haal je dus elementen met index één en twee op, maar niet het element met index drie.
Zowel de index voor als na de dubbele punt is optioneel. Laat je de eerste index weg, dan begin je bij het begin (index 0). Laat je de laatste index weg, dan slice je tot het einde.
mijn_lijst = [1, "b", "drie", 4, "V", ]
mijn_slice = mijn_lijst[:3] # [1, "b", "drie"]
mijn_slice = mijn_lijst[3:] # [4, "V"]
Omdat beide indexen optioneel zijn, kun je ze ook beide weglaten:
mijn_lijst = [1, "b", "drie", 4, "V", ]
mijn_slice = mijn_lijst[:] # [1, "b", "drie", 4, "V"]
Je maakt dan een slice vanaf het begin, tot het einde. Feitelijk maak je dan dus een kopie van de eerste list
.
Een slice werkt ook met negatieve indexering.
Controleren of een element zich in een lijst bevindt
Soms wil je eerst weten of een element zich in een list
bevindt. De meest handige manier om dit te doen is met in
, of als je wilt weten of een element zich niet in een list
bevindt met not in
:
mijn_lijst = ["a", "a", "b", "b", "c", ]
print("a" in mijn_lijst) # True
print("d" in mijn_lijst) # False
print("e" not in mijn_lijst) # True
Andere manieren om te controleren of een element zich in een list
bevindt zijn .index()
en .count()
. Met .index()
geef je een waarde op, en krijg je de index van het eerste element met die waarde terug. Met .count()
geef je een waarde op en krijg je terug hoeveel elementen met die waarde zich in de list
bevinden.
mijn_lijst = ["a", "a", "b", "b", "c", ]
# Met index()
print(mijn_lijst.index("a")) # 0
print(mijn_lijst.index("d")) # Fout
# Met count()
print(mijn_lijst.count("b")) # 2
print(mijn_lijst.count("d")) # 0
Hoe je de fout op regel vijf verwerkt leer je het hoofdstuk Werken met uitzonderingen. Het is afhankelijk van de context welk instrument je gebruikt. Soms is in
voldoende, maar zoals uit bovenstaande voorbeelden blijkt weet je dan nog niet dat de waarde a
zich vaker in de list
bevindt.
Itereren langs elementen in een lijst
Het itereren langs elementen in een list
heb je al meerdere malen voorbij zien komen in voorgaande hoofdstukken. Met een for-loop
ga je elk element in een list
langs en kun je daar iets mee doen. Wát je ermee doet is aan jou, het blok in een for-loop
kan net zo lang of kort zijn als nodig is.
Een for
-statement heeft de volgende opbouw:
for <naam> in <lijst>:
blok uitgevoerd voor elk element <naam>
Elke ronde wordt er een element uit de list
gehaald en toegewezen aan de variabele <naam>
. In de rest van de for-loop
kun je die variabelen dan ook gebruiken zoals elke variabele.
Hoe je de variabele noemt, maakt in principe niet uit. Soms zie je dat het heel algemeen blijft (i
, item
, x
), maar handiger is het om het iets beschrijvender te maken. Bevat je list
boektitels, dan is book
logisch. Bevat de list
gebruikers, dan noem je het user
, etc.
Een veelgehoorde uitdrukking in het programmeren is dat code vaker wordt gelezen dan geschreven. Jij en je collega’s lezen code om te begrijpen wat er gaande is, wat een functie ook alweer doet, etc. Daarom is het belangrijk om variabelen, functies, klassen en namen in een Dit geldt ook voor projecten waar je in je eentje aan werkt. Over zes maanden ben je blij als je oude code duidelijk is omschreven! |
Soms wil je niet alleen dat het element aan de variabele wordt gekoppeld, maar wil je ook de index van de elementen bijhouden. Dit doe je met enumerate
. Optioneel geef je op waar de index moet starten.
users = ["marie", "john", "ali", ]
# Index start bij 0
for index, user in enumerate(users):
print(f"Index {index}: {user}")
# Index start bij 1
for ronde, user in enumerate(users, 1):
print(f"Ronde {ronde}: {user}")
In plaats van één naam op te geven in de for
-statement, geef je er twee op gescheiden door een komma. Verder roep je de functie enumerate
aan met de list
als argument (en optioneel de start van de index).
Je ziet dat het ook hier weer niet uitmaakt hoé je de variabelen noemt. In het eerste geval is het index, user
en in het tweede geval ronde, user
.
Elementen in een lijst sorteren en omkeren
Een list
kun je zowel sorteren als omkeren.
Sorteren
Met de .sort()
methode sorteer je de elementen in een list
. Standaard is de sortering van laag naar hoog. Je kunt .sort(reverse=True)
gebruiken om de sortering om te draaien.
mijn_lijst = ["b", "a", "d", "c", ]
mijn_lijst.sort()
print(mijn_lijst) # ["a", "b", "c", "d"]
Dit sorteren past de bestaande list
aan, er wordt dus geen nieuw object aangemaakt. Het sorteren werkt alleen als de elementen in de list
met elkaar vergeleken kunnen worden.
mijn_lijst = ["a", 2, "b", 3, ]
mijn_lijst.sort() # Fout
Voer je deze code uit, dan krijg je een foutmelding die aangeeft dat het sorteren niet lukt.
Tot slot kun je opgeven hoe je wilt sorteren, door een functie mee te geven aan .sort()
die de sleutel ophaalt uit elk element en dat gebruikt om te sorteren. Je kunt bijvoorbeeld de ingebouwde functie len()
gebruikte om de lengte van een str
te bepalen.
print(len("test")) # 4
# Gebruik len als sleutel om te sorteren
mijn_lijst = ["aaa", "bb", "c", ]
mijn_lijst.sort(key=len)
print(mijn_lijst) # ["c", "bb", "aaa"]
Met sort(key=len)
zorg je ervoor dat eerst len()
op elk element wordt uitgevoerd, dit levert voor elk element een waarde op (3, 2 en 1 in dit voorbeeld) en deze waarden worden gebruikt om de list
te sorteren.
In plaats van een list
in-place te sorteren, kun je ook de ingebouwde functie sorted()
gebruiken. Dit doet hetzelfde als sort()
, maar levert een nieuwe list
op. Het voordeel van sorted
is dat het niet alleen op list
werkt, maar bij alle iterables, zoals een tuple
.
Omkeren
Naast een list
sorteren, kun je een list
ook omkeren. Dit doe je met de methode .reverse()
of de ingebouwde functie reversed()
.
mijn_lijst = [1, 2, 3, 4, ]
mijn_lijst.reverse()
print(mijn_lijst) # [4, 3, 2, 1]
Net als bij .sort()
levert .reverse()
geen nieuw object op. Met de ingebouwde functie reversed()
bereik je dit wel.
Elementen aan een lijst toevoegen
Een veel voorkomende taak bij een list
is het toevoegen van elementen. Hiervoor zijn drie methodes beschikbaar.
-
.append()
-
.insert()
-
.extend()
append
Met .append()
voeg je een element toe aan het einde van de list
. Je kunt één element tegelijk toevoegen. Bijvoorbeeld:
mijn_lijst = []
mijn_lijst.append("a")
print(mijn_lijst) # ["a"]
Je kunt elk type element toevoegen, let hierbij wel op dat als je bijvoorbeeld een list
of tuple
toevoegt, het één element aan het einde van de oorspronkelijke list
wordt:
mijn_lijst = ["a", ]
mijn_lijst.append([1, 2, 3]) # Voeg een lijst toe
print(mijn_lijst) # ["a", [1, 2, 3]]
insert
Met .insert()
voeg je een enkele item toe in de list
. Je geeft het element dat je wilt toevoegen door, samen met de index waar het element geplaatst moet worden. De elementen erna zullen allemaal één index opschuiven.
mijn_lijst = ["a", "c", "d", ]
mijn_lijst.insert(1, "b") # Voeg 'b' toe op index 1
print(mijn_lijst) # ["a", "b", "c", "d"]
Net als bij .append()
kun je bijvoorbeeld een list
toevoegen, maar wordt dit één element in de oorspronkelijke list
.
Elementen uit een lijst verwijderen
Net als je op verschillende manieren elementen aan een list
kunt toevoegen, zijn er ook verschillende manieren om één of meerdere elementen te verwijderen.
remove
Met de .remove()
methode verwijder je een element op basis van de waarde. Het eerste element in de list
met de opgegeven waarde wordt verwijderd (de rest dus niet, als er meerde elementen met die waarde zijn). Wordt de waarde niet gevonden, dan ontstaat een fout.
mijn_lijst = [1, 2, 3, 2, ]
mijn_lijst.remove(2) # Verwijder element met waarde 2
print(mijn_lijst) # [1, 3, 2]
mijn_lijst.remove(0) # Fout
pop
Met de .pop()
methode verwijder je een element op basis van de index. Het element wordt teruggegeven, zodat je het kunt opslaan in een variabele.
mijn_lijst = [1, 2, 3]
element = mijn_lijst.pop(1) # pop element met index 1
print(element) # 2
print(mijn_lijst) # [1, 3]
Geef je geen index op, dan verwijder je het laatste element in de list
.
del
Met het ingebouwde keyword del
verwijder je één of meerdere elementen uit een list
, op basis van een index of een slice.
mijn_lijst = [1, 2, 3, 4, 5]
del mijn_lijst[1] # Verwijder element met index 1
print(mijn_lijst) # [1, 3, 4, 5]
del mijn_lijst[1:3] # Verwijder elementen met index 1 tot 3
print(mijn_lijst) # [1, 5]