Python-generators: efficiënte iteratie en geavanceerde use cases
Python-generators
Ontdek hoe Python-generators iteratie vereenvoudigen, boilerplate reduceren en geheugengebruik verbeteren ten opzichte van traditionele iterators.
Wat zijn generators?
Een custom iterator bouwen in Python vereist meestal een klasse die __iter__() en __next__() implementeert, interne state beheert en StopIteration gooit wanneer klaar. Generators elimineren deze boilerplate door je toe te staan een simpele functie te schrijven die waarden één voor één oplevert.
Kortom, een generator is een functie die een iterator retourneert. De functie-body voert lazy uit, pauzeert na elke yield en hervat bij opeenvolgende aanroepen.
Generators aanmaken in Python
Een generator definiëren is zo simpel als een normale functie schrijven en return vervangen door yield:
def mijn_gen():
n = 1
print('Dit wordt eerst geprint')
yield n
n += 1
print('Dit wordt tweede geprint')
yield n
n += 1
print('Dit wordt laatst geprint')
yield n
mijn_gen() aanroepen retourneert een iterator die pas begint met uitvoeren wanneer next() aangeroepen wordt.
a = mijn_gen()
next(a) # print eerste bericht en retourneert 1
next(a) # print tweede bericht en retourneert 2
next(a) # print laatste bericht en retourneert 3
next(a) # gooit StopIteration
Lokale variabelen persisteren tussen yields, maar de generator kan slechts één keer geïtereerd worden. Om opnieuw te beginnen, maak een nieuwe instantie aan.
Omdat een generator een iterator is, kun je er direct over loopen:
for item in mijn_gen():
print(item)
Algemene generator-patronen
Een string omkeren
def omgekeerde_str(s):
for i in range(len(s)-1, -1, -1):
yield s[i]
for char in omgekeerde_str('hallo'):
print(char)
Werkt met elk iterable (lijst, tuple, etc.).
Generator-expressies
Anonieme generators kunnen aangemaakt worden met haakjes, vergelijkbaar met list comprehensions:
mijn_lijst = [1, 3, 6, 10]
# List comprehension
kwadraten_lijst = [x**2 for x in mijn_lijst]
# Generator-expressie
kwadraten_gen = (x**2 for x in mijn_lijst)
print(kwadraten_lijst)
print(kwadraten_gen)
De generator levert waarden op aanvraag:
a = (x**2 for x in mijn_lijst)
print(next(a)) # 1
print(next(a)) # 9
print(next(a)) # 36
print(next(a)) # 100
next(a) # StopIteration
Generator-expressies kunnen direct aan functies als sum of max doorgegeven worden zonder de omringende haakjes.
Waarom generators gebruiken?
- Beknopte implementatie: Vervangt verbose iterator-klassen met een paar regels code.
- Geheugenefficiënt: Levert één item per keer, ideaal voor grote of oneindige sequences.
- Oneindige streams: Vertegenwoordigt eindeloze databronnen (bijv.
while True: yield). - Pipeline-compositie: Keten meerdere generators voor schone, leesbare dataverwerking.
Voorbeeld: Macht van twee
def macht_twee_gen(max_n=0):
n = 0
while n < max_n:
yield 2 ** n
n += 1
Voorbeeld: Som van kwadraten van Fibonacci-getallen
def fibonacci_getallen(aantal):
a, b = 0, 1
for _ in range(aantal):
a, b = b, a + b
yield a
def kwadraten(nums):
for n in nums:
yield n ** 2
print(sum(kwadraten(fibonacci_getallen(10)))) # 4895
Generators stellen elegante, efficiënte en onderhoudbare code in voor een breed scala aan iteratiescenario's.
Python
- Python Operators onder de knie krijgen: Een uitgebreide gids
- Python Functie-argumenten onder de knie krijgen: Positionele, Keyword en Default Parameters
- Python-dictionaries beheersen: aanmaken, manipuleren en geavanceerde technieken
- Python-generators: efficiënte iteratie en geavanceerde use cases
- Python-closures uitgelegd: hoe geneste functies variabelen vangen
- Python-decorators beheersen: functies verbeteren met expert-technieken
- Python lambda-functies beheersen: praktische voorbeelden & best practices
- Python abs()-functie: absolute waarden berekenen voor getallen & complexe getallen
- Python round()-functie uitgelegd met praktische voorbeelden
- Python's map()-functie beheersen: syntaxis, voorbeelden en best practices
- Python's yield meesteren: Generator vs Return – Een praktische gids