Inhoud
Lussen in Python
Een van de voordelen van een computer is, dat ze zonder klagen oneindig lang een repenterende taak kan uitvoeren. Zo'n repenterende taak wordt in computerland een “iteratie” genoemd.
Een iteratie beschrijf je als volgt:
- Begin met een of meerdere taken die uitgevoerd moeten worden
- Als alle taken uitgevoerd zijn, dan begin je weer opnieuw bij '1'
Deze lus zal je programma eeuwig uit blijven voeren, totdat de bewerking door een of andere reden van buitenaf wordt onderbroken. Daarom bevatten de meeste programma's een (of meerdere) conditie(s) om de iteratie af te breken.
in Python zijn er een tweetal type interatie statements:
- De for loop:
for variabele in een range:
- De while loop:
while conditie:
De volgende hoofdstukken beschrijven deze iteraties in detail.
De "for" lus
In de for iteratie, lopen we simpelweg een vooraf bepaalde reeks af en doe iets met de geselecteerde waarde. Wanneer we aan het eind van de lus komen, nemen we de volgende waarde en beginnen van vooraf aan. De syntax van het for statement is dan als volgt:
for [variabele] in [collectie]: [aktie(s)] ga verder...
Stel, we willen de tafel van 5 uitrekenen. Uiteraard kun je dan tiek keer de berekening uitvoeren, maar al we dit met een for list doen, beginnen we met één, vermenigvuldigen dit met vijf, en pakken dan het volgende getal, totdat we getal tien hebben gehaald. Dit kan er dan als volgt eruitzien:
for i in (1,2,3,4,5,6,7,8,9,10): print(i,"x", 5, "=", i*5) print("Klaar")
Het resultaat ziet er dan als volgt uit:
1 x 5 = 5 2 x 5 = 10 3 x 5 = 15 4 x 5 = 05 5 x 5 = 25 6 x 5 = 30 7 x 5 = 35 8 x 5 = 40 9 x 5 = 45 10 x 5 = 50 Klaar
In de bovenstaande code, defineren we ieder element. Wanneer we heel veel getallen hebben, is dit natuurlijk wel lastig om alle elementen te geven. Daarom is dit gemakkelijker te beschrijven.met behulp van de funktie range.
De syntax van deze funktie is: range((begin),eindwaarde,(stap))
, waarbij geldt:
- begin: De eerste te gebruiken waarde (optioneel), default: begin=0
- eind: De eindwaarde exclusief. Deze waarde moet opgegeven worden, maar wordt niet meegenoment in de range.
- stap: De waarde waarmee door de range heengestapt moet worden (optioneel), default: stap=1
We kunnen nu de eerste code verbeteren door, waarbij we beginnen met 1, eindigen met 11 (wordt niet meegenomen), met stapwaarde 1:
for i in range (1,11,1): print(i,"x", 5, "=", i*5) print("Klaar")
Omdat de stapwaarde per default “één” is, kunnen we de funktie vereenvoudigen door de stapwaarde weg te laten, waardoor het programma als volgt eruit ziet:
for i in range (1,11): print(i,"x", 5, "=", i*5) print("Klaar")
We kunnen zelfs de beginwaarde weglaten (waarbij we er rekening voor moeten houden dat de beginwaarde per default “nul” is. Omdat we voor de eerste iteratie getal 1 willen gebruiken, moeten we er een bij optellen om de juiste berekening te printen. De eindwaarde zal dan dus ook met één verlaagd moeten worden! Het programma wordt nu:
for i in range (10): print(i+1,"x", 5, "=", (i+1)*5) print("Klaar")
Een for lus hoeft niet specifiek met getallen te werken, we kunnen bijvoorbeeld ook door een karakter array (oftewel string) heenlopen:
for c in "Python": print (c)
Het resultaat hiervan is dan dus:
P y t h o n
En zelfs mag er een string gebruikt worden om de collectie te bepalen. Als voorbeeld, wat dezelfde output levert als bovenstaand programma'tje:
tekst = "Python" for c in tekst: print (c)
En uiteraard mag dat ook met getallen:
selectie = (1,2,3,4,5,6,7,8,9,10) for i in selectie: print(1,"x", 5, "=", i*5) print("Klaar")
En nu een programma'tje, wat de tafel weergeeft die jij graag wilt zien, Je vraagt hierbij om een getal waarvan je de tafel wilt zien en berekent dze in een for loop.
- tafel.py
#! /usr/bin/env python3 # ======================== # Programma naam: tafel.py ''' Dit programma berekent de tafel van het getal wat opgegeven wordt. ''' tafel = float(input("Bereken de tafel van: ")) # Geeft het getal invoor de te berekenen tafel print("De tafel van",tafel,":") for i in range(10): # Bereken de tafel van "getal" print(i+1, "x", tafel, "=", (i+1)*tafel) print("Klaar");
De "while" lus
Een andere manier van een lus bouwen is met behulp van de “while” lus. Deze lus kun je beschrijven als volgt:
while [comditie], die iets, (bewerk de conditie,) en begin opnieuw
.
Syntax:
eerste deel van het programma while conditie: doe iets doe eventueel nog wat pas conditie voorwaarde aan (om ervoor te zorgen dat de while lus kan eindigen) ga verder met het programma...
Om in de lus te komen, moet de conditie waar zijn. Anders, als de conditie niet waar is, zal de lus helemaal overgeslagen worden. Daarna, als het programma in de lus komt, moet je binnen die lus kijken naar de conditie (en aanpassen), om ervoor te zorgen dat de lus uiteindelijk eindigt.
Stel voor, we willen de while lus gebruiken om een drietal getallen op te geven. Daarvoor willen we het aantal ingegeven getallen tellen en stoppen als het derde getal ingegeven is. Dat betekent dat je begint met “nog geen getallen opgegeven” en eindigd als “het aantal opgegeven getallen drie is”. Wat met het opgegeven getal gebeurt, is hier niet van belang, dus printen we dit gewoon!
Het programma'tje ziet er als volgt uit:
- getallen.py
#! /usr/bin/env python3 # =========================== # Programma naam: getallen.py aantal = 0 # Er is nog geen getal opgegeven while not aantal == 3: # Zolang er geen drie getallen opgegeven zijn, ga verder getal = float(input("Geef getal: ")) # Geef een getal op aantal += 1 # Verhoog het aantal opgegeven getallen met één print("Getal", aantal, "is", getal) print("Klaar")
De uitleg van deze code:
- We beginnen met het aantal opgegeven getallen is '0'
- Zolang het aantal opgegeven getallen niet gelijk is aan '3'
- Vraag om een getal en
- Hou bij hoeveel getallen er opgegeven zijn (verhoog met '1').
Let op: in dit programma'tje controleren we op not aantal == 3
, maar mijn voorkeur heeft om hier te controleren op dat het aantal getallen is kleiner dan drie (zodat ook met vier of hoger, we niet meer in de lus gaan). De while expressie wordt dan: while getal < 3:
!
Ik heb overigens hier een instruktie gebruikt, die nog niet eerder behandeld is. Het gaat hierbij om de instruktie: aantal += 1, waarbij de operator “+=” aangeeft, tel de waarde achter de operator op bij de variabele voor de operator en sla het resultaat op in diezelfde variabele. De betreffende instruktie kan dus ook geschreven worden als “aantal = aantal + 1”.
Deze verkorte schrijfwijze kan met de meeste rekenstrukties gebruikt worden, bijvoorbeeld:
- i += 1
- i -= 7
- i *= 5
- i /= 2
- …
De "do-while" lus
Bij de “while-do” lus gaan we de lus in, nadat de conditie gecontroleerd is. Dat betekent dat er een mogelijkheid bestaat dat er niet in de lus gegaan wordt, als de conditie niet waar is. Met andere woorden, het aantal keren dat de lus doorlopen wordt, is ≥ nul.
Bij de “do-while” lus, wordt eerst door de lus heen gelopen, en daarna wordt de conditie pas gecontroleerd. De syntax voor een do-while lus is als volgt:
do aktie(s) until conditie
Helaas is deze constructie niet in python beschikbaar, maar via een omweg kunnen we wel iets gelijkwaardigs maken. Daarvoor hebben we twee speciale instrukties 1):
- break: Hiermee springen we uit de lus en gaan verder met het programma na de lus.
- continue: hiermee slaan we de rest van de lus over en beginnen weer vooraan met de lus.
Wat we nu gaan doen is een “oneindige” lus maken (while True:
), terwijl we in de lus een conditioneel statement om uit de lus te springen. Daardoor gaan we altijd de lus in, en springen uit de lus met een specifieke conditie. Daardoor wordt de “do-while” lus geëmuleerd.
Syntax “do-while” emulatie:
while True: aktie(s) # De uit te voeren akties, # worden tenminste één keer uitgevoerd if conditie: break # Hiermee spring je direct uit het programma. # Wanneer continue i.p.v. break gebruikt wordt, # dan wordt de rest van de lus overgeslagen en # de lus begint weer van voor af aan. de rest van de lus rest van het programma
We gaan u als voorbeeld een programma maken met een do-while simulatie. Daarbij vragen we om een getal in te voeren, waarbij de lus stopt als het ingegeven getal nul (0) is. Verder negeert de lus negatieve getallen of getallen groter dan tien (10). Ook hier geldt, wat we met het ingegeven getal doe is niet belang is, dus printen we het hier gewoon.
De code wordt als volgt:
- getal.py
#! /usr/bin/env python3 # ======================== # Programma naam: getal.py print("Invoeren van getallen (0: einde") while True: getal = float(input("Geef getal: ") # Invoer van een getal if getal == 0: # Beëindig de lus bij invoer nul break if getal < 0 or getal > 10: # Negeer een negatief getal of continue # een getal, groter dan tien print("Het ingetoetste getal is:", getal) print("klaar")
Uitleg van de code:
- We beginnen met een “oneindige” lus te definiëren
while True:
- De lus wordt in ieder geval één keer gestart, dus kunnen we hier een getal vragen
- Als er een nul ingegeven is, dan springen we hier uit de lus, de rest negerend,
- Zo niet, dan bekijken we of het getal negatief is, of dat het getal groter dan tien is.
In dat geval negeren we de rest van de lus en beginnen we opnieuw met de lus
Geneste lussen
Stel voor dat we een programma moeten maken, waarin we met een combinatie van meerdere gegevens moeten verwerken. In dat geval kunnen we gebruik maken van zogenaamde geneste lussen. De syntax hiervan is:
for variabele1 in collectie1: for variabele2 in collectie2: doe iets met variabele1 en variabele2
of
while conditie1: while conditie2: die iets met conditie1 en met conditie2
Laten we eens kijken naar een programma dat de getallen 1 t/m 10 met elkaar moeten vermenigvuldigen, wat we kunnen maken met zowel een for als met een while lus. Het programma met de while lus is het simpelste uit te leggen:
- initialiseer de eerste variabele met 1
- ga een while lus in en controleer of die eerste variabele niet groter dan 10 is
- initialiseer de tweede variabele met 1
- ga een tweede while lus in en controleer de tweede variabele op niet groter dan 10
- vermenigvuldig de eerste met de tweede variabele
- verhoog y met één in de tweede lus
- verhoog x met één in de eerste lus (nadat de tweede lus afgelopen is)
De code:
- vermenigvuldig_1.py
#! /usr/bin/env python3 # =================================== # Programma naam: vermenigvuldig_1.py x = 1 while x <= 10: y = 1 while y <= 10: print (x, "x", y, "=", x*y) y += 1 x += 1 print("klaar")
Het programma met de for lus is iets lastiger uit te leggen, omdat range(10) loopt van 0..9 ! Daarom moeten we wat doen met de variabelen (één bij optellen), om de juiste vermenigvuldiging te maken. Het aantal regels code is overigens wel minder, hierbij de uitleg:
- Laat x van 0 t/m 9 lopen
- Laat y van 0 t/m 9 lopen
- Vermenigvuldig (x+1) met (y+1).
Het programma ziet er nu dan als volgt uit:
- vermenigvuldig_2.py
#! /usr/bin/env python3 # =================================== # Programma naam: vermenigvuldig_2.py for x in range(10): for y in range(10): print (x+1, "x", y+1, "=", (x+1)*(y+1)) print("klaar")
Nu wil ik nog een opmerking maken over dit programma. Omdat we welliswaar alle getallen met elkaar willen vermenigvuldigen, lopen we hier twee keer alle getallen door. Echter, de berekening “1×2” is hetzelfde als de berekening “2×1”, dus eigenlijk een duplicatie. Als we nu deze duplicatie eruit willen hebben, dan kunnen we stellen dat als we alle berekeningen voor x=1 hebben gehad, we de berekening voor y=1 niet meer hoeven te doen voor x=2. We kunnen nu starten met y=2, oftewel y=x!
De verbeterde geneste “for” lus:
- vermenigvuldig_3.py
#! /usr/bin/env python3 # =================================== # Programma naam: vermenigvuldig_3.py for x in range(10): for y in range(x,10): print (x+1, "x", y+1, "=", (x+1)*(y+1)) print("klaar")
Als laatste opmerking: Nesten van lussen is niet gelimiteerd tot twee lussen. Je mag zodiep nesten als je wilt! Maar let op, het wordt er niet altijd duidelijker van.
De "else" instruktie
Als laatste wat ik wil behandelen is de else instruktie, die eenmalig wordt uitgevoerd als de lus conditie niet waar is (geworden). Je zult zeggen, dit is hetzelfde als doorgaan met de op de lus volgende code, maar dat is niet helemaal waar. Indien je uit de lus gaat met de break instructie, wordt ook echt de hele resterende lus code genegeerd, inclusief het else blok. Daatdoor kun je een instruktie plannen, die uitgevoerd wordt als de lus helemaal tot het einde is doorgelopen, maar niet uitgevoerd wordt, wanneer er bewust uit de lus wordt gesprongen.
Een voorbeeld:
- getal_lus.py
#! /usr/bin/env python3 # ============================ # Programma naam: getal_lus.py for i in range(10): y = float(input("y: ")) if y = 0: print("Eind door input van nul") break print("Getal", i, "is", y) else: print("Eind doordat de hele range doorlopen is") print("Klaar")
Dit programma zal maximaal tien keer om een getal vragen. Maar als tijdens het ingeven van de getallen een nul wordt ingegeven, zal via de “break”-instructie uit de lus gesprongen worden en “Klaar”geprint worden. De print instruktie in het else-blok zal niet uitgevoerd worden.
Als er bijn het ingeven van de getallen er géén nul ingevoerd wordt, dan zal de lus volledig aflopen en wordt de print in het else-blok uitgevoerd, voordat het woordje “Klaar” geprint wordt.
Zo'n else instruktie is ook te gebruiken in een while lus, waarbij het else statement ook genegeerd wordt, als je de while lus verlaat met een break statement. Let wel, bij een do-while emulatie is het else statement overbodig, omdat je altijd zo'n while True: lus elimineerd door middel van een break. Daardoor zal daar het else-blok nooit uitgevoerd worden.