Hoofdstuk 4 - Werken met Lijsten

01 - Lijsten & lussen ( for-loop )
  • Met elk item in een lijst iets doen? Gebruik een lus (for-loop)
poisons = ['Red Bull', 'Monster', 'Pepsi']
for x in poisons:
    print(x + " kun je drinken")
Red Bull kun je drinken
Monster kun je drinken
Pepsi kun je drinken

  • De x in bovenstaande for-loop is een zelfverzonnen variabelenaam
  • De naam x is niet zelfverklarend en kan beter vervangen worden door poison
poisons = ['Red Bull', 'Monster', 'Pepsi']
for poison in poisons:
    print(poison + " kun je drinken")
Red Bull kun je drinken
Monster kun je drinken
Pepsi kun je drinken

  • Welk karakter of woord je gebruikt in de for-loop mag je zelf beslissen
  • Met meervoud en enkelvoud werken voor de lijst- en variabelenaam komt veel voor
  • De zelfverzonnen variabele naam x of poison krijgt - bij elke iteratie (herhaling) - de volgende waarde uit de lijst
  • Achter de eerste regel van de for-loop plaats je een dubbele punt (gevolgd door een enter)
  • De opdracht(en) die je bij elke iteratie van de for-loop wilt uitvoeren staan iets ingesprongen (4 spaties)
  • Als de for-loop elk item in de lijst heeft gehad wordt hij gestopt en zal Python verder gaan met regels onder de for-loop
poisons = ['Red Bull', 'Monster', 'Pepsi']
for item in poisons:
    print("Waarschuwing: deze loop kan je hartslag verhogen…")
    print(item + " noemen we in Python poison")
print("In de supermarkt noemen ze het actie")   
Waarschuwing: deze loop kan je hartslag verhogen…
Red Bull noemen we in Python poison
Waarschuwing: deze loop kan je hartslag verhogen…
Monster noemen we in Python poison
Waarschuwing: deze loop kan je hartslag verhogen…
Pepsi noemen we in Python poison
In de supermarkt noemen ze het actie
  • Als je met elk item uit een lijst iets wil doen, dan is een for-loop een goede manier om dat te doen
  • Met het inspringen van een regel geef je aan dat de regel hoort bij de for-loop
02 - Fouten met het inspringen
  • Python gebruikt inspringen om te bepalen of een regel code verbonden is met de regel erboven
  • Het feit dat Python inspringen gebruikt, maakt de code schoon en makkelijk te lezen
  • Python dwingt je met witruimtes om netjes opgemaakte code te schrijven met een duidelijke visuele structuur

Vergeten in te springen
poisons = ['Red Bull', 'Monster', 'Pepsi']
for poison in poisons:
print(poison + " kun je drinken")
. . . . print(poison + " kun je drinken")
. . . . ^
IndentationError: expected an indented block

Onnodig inspringen
poisons = ['Red Bull', 'Monster', 'Pepsi']
    print("In de supermarkt noemen ze het actie") 
. . . . print("In de supermarkt noemen ze het actie") 
IndentationError: unexpected indent

Dubbele punt vergeten
poisons = ['Red Bull', 'Monster', 'Pepsi']
for poison in poisons
    print(poison + " kun je drinken")
. . . . for poison in poisons
. . . . . . . . . . . . . . . . .^
SyntaxError: invalid syntax

03 - De range( )-functie
  • Met de range( )-functie kun je getallen genereren
for number in range(1,5):
    print(number)
1
2
3
4

  • Je kunt de getallen direct in een lijst zetten
  • Plaats de range( )-functie dan in de lijst( )-functie
numbers = list(range(1,5))
print(numbers)
[1, 2, 3, 4]

Een patroon en de range( )-functie
  • Door een derde waarde toe te voegen aan de range( )-functie kun je grotere stappen maken
numbers = list(range(8,81,8))
print(numbers)
[8, 16, 24, 32, 40, 48, 56, 64, 72, 80]
  • Nummer 1 = Startnummer
  • Nummer 2 = Eindnummer (exclusief zichzelf)
  • Nummer 3 = Stapgrootte

Een lijst met kwadraten
  • Python gebruikt ** voor een kwadraat (square)
# De kwadraten van de getallen 1 t/m 10 in een lijst
squares = []
for number in range(1, 11):
    item = number ** 2 
    squares.append(item)
print(squares)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
  • Door de variabele 'item' weg te laten kan hetzelfde resultaat verkregen worden met minder code
  • Elke nieuwe waarde wordt rechtstreeks aan de lijst toegevoegd
# De kwadraten van de getallen 1 t/m 10 in een lijst
squares = []
for number in range(1, 11):
    squares.append(number**2)
print(squares)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Je kunt beide benaderingen gebruiken als je complexe lijsten maakt. Soms maakt het gebruik van een tijdelijke variabele je code beter leesbaar; soms maakt het je code juist onnodig lang. Richt je eerst op het schrijven van code die je duidelijk begrijpt en doet wat het moet doen. Wanneer je code herziet kun je kijken naar een efficiëntere benadering.


04 - Eenvoudige statistieken met getallenlijsten
  • Python heeft een aantal specifieke functies voor getallenlijsten
numbers = [7,13,27.3,864,25920]
print(min(numbers))
7

numbers = [7,13,27.3,864,25920]
print(max(numbers))
25920

numbers = [7,13,27.3,864,25920]
print(sum(numbers))
26831.3

numbers = [7,13,27.3,864,25920]
print(len(numbers))
5

# Het gemiddelde berekenen is een combinatie van de vorige built-in functions
numbers = [7,13,27.3,864,25920]
average = sum(numbers) / len(numbers)
print(average)
5366.26

In SQL heten ze aggregatiefuncties. In Python noemen we ze built-in functions.

05 - List Comprehensions
  • Met List Comprehensions kun je met minder code een nieuwe lijst maken
  • List Comprehensions worden niet aan beginners voorgeschoteld
  • Je collega's gebruiken waarschijnlijk wel List Comprehensions
  • De List Comprehension combineert de for-loop en het maken van een nieuw item in 1 regel
  • Een List Comprehension is vooral bedoeld om minder code te schrijven
# De kwadraten van de getallen 1 t/m 10 in een lijst (zonder List Comprehension)
squares = []
for number in range(1, 11):
    item = number ** 2 
    squares.append(item)
print(squares)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

# De kwadraten van de getallen 1 t/m 10 in een lijst (met een List Comprehension)
squares = [number**2 for number in range(1,11)]
print(squares)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

  • In bovenstaande list comprehension staat geen dubbele punt achter de for-loop
  • Als je lijsten maken goed onder de knie hebt en je merkt dat je dingen vaker herhaalt -> begin dan met het schrijven van je eigen list comprehensions
06 - Een lijst Splitsen (subset)
  • Om een splitsing te maken specificeer je de index van het eerste en het laatste item waarmee je wilt werken
  • Het is: inclusief het eerste item - exclusief het laatste item
players = ['Apple', 'Google', 'Amazon', 'Meta', 'TikTok']
print(players[0:3])
['Apple', 'Google', 'Amazon']

  • Als je de eerste index van een splitsing weglaat begint Python automatisch aan het begin van de lijst
  • Als je de laatste index weglaat van een splitsing loopt de subset altijd tot het einde van de lijst
players = ['Apple', 'Google', 'Amazon', 'Meta', 'TikTok']
print(players[:2])
['Apple', 'Google']
players = ['Apple', 'Google', 'Amazon', 'Meta', 'TikTok']
print(players[3:])
['Meta', 'TikTok']

Een for-loop door een subset
  • Een for-loop gebruiken op een selectie (subset) van een lijst kan ook
players = ['Apple', 'Google', 'Amazon', 'Meta', 'TikTok']
print("Bij de Magnificent Seven horen: ")
for player in players[:4]:
    print(player)
Bij de Magnificent Seven horen:
Apple
Google
Amazon
Meta

Een kopie van een lijst maken
  • Het kopiëren van een lijst is soms handig en gaat als volgt
players = ['Apple', 'Google', 'Amazon', 'Meta', 'TikTok']
players_copy = players[:]
print(players)
print(players_copy)
['Apple', 'Google', 'Amazon', 'Meta', 'TikTok']
['Apple', 'Google', 'Amazon', 'Meta', 'TikTok']
  • Door geen indexen (indices) op te geven wordt elk item van de lijst gekopieerd
  • Het opgeven van een 'lege' subset [ : ] is nodig om de lijst te kopiëren

  • Als je geen 'lege' subset [ : ] opgeeft wordt er ook geen kopie gemaakt
players = ['Apple', 'Google', 'Amazon', 'Meta', 'TikTok']
players_copy = players
print(players)
print(players_copy)

print("Nu komt er een toevoeging alleen in de oorspronkelijke lijst:")
players.append('CBS')

print(players)
print(players_copy)
['Apple', 'Google', 'Amazon', 'Meta', 'TikTok']
['Apple', 'Google', 'Amazon', 'Meta', 'TikTok']
Nu komt er een toevoeging alleen in de oorspronkelijke lijst:
['Apple', 'Google', 'Amazon', 'Meta', 'TikTok', 'CBS']
['Apple', 'Google', 'Amazon', 'Meta', 'TikTok', 'CBS']

In dit voorbeeld wordt players_copy gelijkgesteld aan players. Er wordt geen kopie gemaakt, maar een verbinding.

07 - Tupels
  • Een lijst kan tijdens het verloop van het programma veranderen
  • Een tupel lijkt op een lijst, maar het grote verschil is dat een tupel niet kan veranderen
  • Waar een lijst [ ] brackets gebruikt daar gebruikt een tupel ( ) haakjes
  • Net als bij lijsten gebruikt een tupel indexen om individuele items te benaderen
numbers = (1.414, 1.732, 2.236)
print(numbers[0])
1.414
  • Als je de waarde van een item in een tupel probeert te wijzigen krijg je een foutmelding
numbers = (1.414, 1.732, 2.236)
numbers[0] = 18
TypeError: 'tuple' object does not support item assignment
  • Met een for-loop kun je alle waarden van een tupel aflopen
numbers = (1.414, 1.732, 2.236)
for num in numbers:
    print(str(num) + " is een speciaal, irrationeel getal")
1.414 is een speciaal, irrationeel getal
1.732 is een speciaal, irrationeel getal
2.236 is een speciaal, irrationeel getal

Een tupel overschrijven
  • Een tupel kan je niet wijzigen
  • Een variabele die een tupel bevat kun je wel wijzigen
  • Je kunt een nieuwe (aangepaste) tupel toewijzen aan een bestaande variabele
numbers = (1.414, 1.732, 2.236)
print(numbers)

numbers = (2,3,5)
print(numbers)
(1.414, 1.732, 2.236)
(2, 3, 5)


  • Vergeleken met lijsten zijn tupels eenvoudige datastructuren
    • Een tupel heeft geen .append( )-functie en .pop( )-functie
    • Er is geen del-functie voor een tupel
    • Een tupel kent geen .sort( )-functie
  • Gebruik een tupel wanneer je een set waarden wilt opslaan die tijdens het programmaverloop niet wijzigen
maand = ('jan', 'feb', 'maa', 'apr', 'mei', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec')
print(maand[5])
jun

08 - Opmaak richtlijnen
  • Code wordt vaker gelezen dan geschreven
  • Makkelijk leesbare code of korte code? => Makkelijk leesbare code!!
  • Bij inspringen in de code gebruiken we vier spaties
  • (Gebruik eventueel een tab en stel deze in je editor in op het zetten van vier spaties)
  • Het advies is om elke regel code minder dan 80 tekens te laten bevatten
  • Maak je tijdens het Python-leer-proces niet druk om het aantal karakters op een regel
  • Gebruik witregels om codeblokken te groeperen maar plaats geen onnodige witregels
  • Meer richtlijnen staan in PEP8, als ze relevant zijn komen ze voorbij in deze cursus

Goede Python-programmeurs houden zich altijd aan bovenstaande richtlijnen, maak er een gewoonte van

Oefening
Quiz

Vraag 1. Wat doet de variabele poison in deze code?

poisons = ['Red Bull', 'Monster', 'Pepsi']
for poison in poisons:
    print(poison + " kun je drinken")



Klopt. In een for-lus loopt de variabele poison langs alle waarden uit de lijst poisons.
Niet helemaal. De variabele achter for wordt bij elke iteratie een volgend item uit de opgegeven lijst.

Vraag 2. Welke versie van de code is volgens de richtlijnen juist ingesprongen?

Variant A

poisons = ['Red Bull', 'Monster', 'Pepsi']
for item in poisons:
    print(item)

Variant B

poisons = ['Red Bull', 'Monster', 'Pepsi']
  for item in poisons:
  print(item)

Variant C

poisons = ['Red Bull', 'Monster', 'Pepsi']
for item in poisons:
print(item)

Variant D

poisons = ['Red Bull', 'Monster', 'Pepsi']
  for item in poisons:
    print(item)



Goed! In deze cursus (en in PEP8) gebruiken we vier spaties inspringing voor code binnen een blok.
Let op. Binnen een for-blok gebruiken we vier spaties inspringing, niet 0 of 2, en de for-regel zelf springt niet in.

Vraag 3. Waarom geeft onderstaande code een foutmelding?

numbers = [1, 2, 3]
for num in numbers:
print(num)



Precies. Na een for-regel verwacht Python een ingesprongen blok. Zonder inspringen krijg je een IndentationError.
Niet goed. Het probleem is het ontbreken van inspringing op de regel met print(num).

Vraag 4. Wat print deze code?

for number in range(1, 5):
    print(number)



Klopt. range(1, 5) genereert de getallen 1 t/m 4; de eindwaarde (5) is exclusief.
Let op. Bij range(start, end) is start inclusief en end exclusief.

Vraag 5. Welke lijst wordt gemaakt door de volgende code?

numbers = list(range(8, 33, 8))
print(numbers)



Juist. Je start bij 8, telt er telkens 8 bij op, en stopt vóór 33. Dat geeft 8, 16, 24 en 32.
Niet helemaal. De derde parameter van range() is de stapgrootte. De reeks stopt vóór 33.

Vraag 6. Welke van de onderstaande functies zijn built-in functions die zinvol zijn op een getallenlijst zoals numbers?

numbers = [7, 13, 27.3, 864, 25920]



Helemaal goed. min, max, sum en len zijn built-in functies die vaak op getallenlijsten worden gebruikt.
Let op. In dit hoofdstuk hebben we de built-in functies min, max, sum en len gebruikt op lijsten met getallen.

Vraag 7. Welke regel code berekent het gemiddelde (mean) van de lijst numbers?

numbers = [7, 13, 27.3, 864, 25920]



Klopt. Het gemiddelde is de som van alle waarden gedeeld door het aantal waarden.
Niet juist. Voor het gemiddelde gebruik je sum(numbers) / len(numbers).

Vraag 8. Wat wordt er geprint?

players = ['Apple', 'Google', 'Amazon', 'Meta', 'TikTok']
print(players[1:4])



Juist. Bij slicing is de eerste index inclusief (1 = Google) en de tweede exclusief (4 = voorbij Meta).
Let op. players[1:4] pakt index 1, 2 en 3: ['Google', 'Amazon', 'Meta'].

Vraag 9. Welke code maakt een echte kopie van de lijst players, zodat wijzigingen in de kopie de originele lijst niet veranderen?

players = ['Apple', 'Google', 'Amazon', 'Meta', 'TikTok']



Goed! Met players[:] maak je een kopie van alle items uit de lijst.
Niet helemaal. players_copy = players maakt alleen een verwijzing; gebruik players[:] om te kopiëren.

Vraag 10. Wat gebeurt er als je deze code uitvoert?

numbers = (1.414, 1.732, 2.236)
numbers[0] = 18



Klopt. Tupels zijn immutabel: je kunt de afzonderlijke items niet wijzigen. Python geeft daarom een TypeError.
Onjuist. Een tupel is niet wijzigbaar. Een poging om numbers[0] te veranderen veroorzaakt een TypeError.