Gevorderde Python-ontwikkelingscursus
Hoofdstuk
>
Niveau
### Generators in Python Generators zijn een speciale klasse van functies die dienen als een eenvoudige manier om iterators te implementeren. Ze maken gebruik van 'yield'-verklaring in plaats van 'return' om waarden één voor één terug te geven, wat geheugenbesparing mogelijk maakt, vooral bij het werken met grote datasets of eindeloze streams van gegevens. Een traditionele functie gebruikt 'return' om een waarde terug te geven en beëindigt de uitvoering. In tegenstelling, een generator onderhoudt de *state* tussen oproepen en hervat de uitvoering vanuit het punt van opschorting elke keer dat `next()` wordt aangeroepen. #### Definiëren van een Generator Het definiëren van een generator lijkt op het definiëren van een normale functie, met het verschil dat 'yield' wordt gebruikt om gegevens terug te geven. Laten we een eenvoudige generator maken die kwadraten van getallen genereert. ```python # Definieer een generatorfunctie def square_numbers(nums): for num in nums: yield num * num my_nums = square_numbers([1, 2, 3, 4, 5]) # Itereer door de generator for num in my_nums: print(num) ``` #### Voordelen van Generators 1. **Lage geheugengebruik**: Generators berekenen elke waarde pas wanneer dat nodig is (lui evalueren), wat betekent dat ze minder geheugen gebruiken dan een lijst die alle waarden vooraf genereert. 2. **Pijplijnverwerking**: Ze maken het gemakkelijk om gegevens door een pijplijn van generatoren te leiden, waardoor bijvoorbeeld complexe data-transformaties mogelijk worden op een efficiënte en leesbare manier. 3. **Eindeloze streams**: Generators kunnen gebruikt worden om eindeloze reeksen te maken zoals reeksen Fibonacci-getallen of het lezen van grote logbestanden stuk voor stuk. #### Conclusie Generators zijn een krachtige functie van Python die het mogelijk maken om code te schrijven die efficiënter en gemakkelijker te lezen is, vooral wanneer je met grote gegevenssets of eindeloze reeksen werkt. Door een *yield* te gebruiken in plaats van *return*, maak je functies die beter schalen en minder geheugen verbruiken.
Een generator maken
Soms wil je consistent waarden genereren in plaats van een eenmalige uitvoer. Net zoals functies werken, worden generators op dezelfde manier geschreven en uitgevoerd, behalve dat ze yield() gebruiken in plaats van return() bij het produceren van een output.
In deze oefening moet je flessen vullen met melk uit de tanks in de stal. Gebruik een generator om het vullen van de flessen te herhalen en ervoor te zorgen dat eventuele overtollige melk uit de tanks wordt verzameld.

Doel
Vul flessen met melk door de melktanks te pompen met generatoren.
De machines die de koemelk opslaan zijn bijna vol, je moet de melk in flessen doen en opslaan voordat het bederft. Dit kan een lastige taak zijn met de normale middelen en de hoeveelheid melk die je kunt winnen kan variëren. Gelukkig kun je generatoren gebruiken om dit proces naadloos en eenvoudig te maken.
Er zijn twee (2) tanks met melk die moeten worden gepompt en gebotteld. Elke machine heeft compartimenten die de melk opslaan, deze worden weergegeven door lijstconstanten genaamd: tank_a en tank_b . Daarnaast heeft elke tank meestal een overschot dat je kunt verzamelen.
Generatoren volgen dezelfde syntax als functies maar zullen yield in plaats van return gebruiken voor hun output. Stel een generator genaamd fill() in en stel deze in met het argument list, dit is waar je de eerder genoemde constanten kunt invoeren.
def fill(list):
for x in range(3):
yield list[x]
yield 5
De generator leest de gegevens van de drie (3) velden in de lijstconstanten, voorgesteld door de compartimenten in de machine, en voegt een surplus toe aan het eind, wat vijf (5) is.
Verzamel het mandje object in het veld om toegang te krijgen tot de noodzakelijke flessen en loop naar de twee (2) X-markeringen om de melk te verzamelen met een for-lus.
Dankzij de yield-instructie kunnen de waarden die door de generator worden geproduceerd direct uit een for-lus worden gelezen. Stel er een op die de collect()-functie gebruikt om de "melk" van de machine te verkrijgen. Volg dat op door speak() te gebruiken om te controleren hoeveel melk elke fles heeft opgeslagen. Bijvoorbeeld:
for bottles in fill(tank_a): player.collect("milk") player.speak("%d pints of milk collected" % (bottles))
Schrijf en gebruik deze for-lus op beide X-markeringen, gebruik op de lichte X-markering het argument tank_a en op de donkere X-markering het argument tank_b om het niveau te voltooien.