Generator (informatica)

informatica

In de informatica is een generator een functie die gebruikt kan worden voor itereren met een lus. Een generator genereert een reeks waarden waar vervolgens over geïtereerd kan worden in een lus. Deze waarden worden na elkaar opgeleverd en telkens wanneer de generator een waarde oplevert kan de lus een keer uitgevoerd worden. Door pas een waarde uit te rekenen wanneer dit nodig is, kan dit efficiëntere code opleveren.

Een generator gedraagt zich als een iterator die een datastructuur doorloopt maar een generator ziet eruit als een functie. Een generator verzorgt zowel het berekenen van de waarden als het doorlopen ervan terwijl een iterator alleen een bestaande datastructuur doorloopt.

Voorbeelden bewerken

Python bewerken

Generator bewerken

In Python wordt een generator geconstrueerd met het sleutelwoord yield. Hiermee wordt een waarde teruggegeven. Dit sleutelwoord kan in een functie gebruikt worden waarmee deze verandert in een generator.

De volgende generator genereert even getallen:

def even_getallen():
    i = 0
    while True:
        if i % 2 == 0:
            yield i
        i += 1

Deze kan als volgt gebruikt worden:

for j in even_getallen():
    # doe iets met j

De generator even_getallen zal nu telkens een getal opleveren (j) die in de lus gebruikt kan worden. Deze lus zal net zo lang worden uitgevoerd zolang de generator nog waarden blijft teruggeven. Elke keer als de generator een waarde teruggeeft, wordt de executie van de generator stilgelegd en wordt de lus een keer uitgevoerd. Als dit is gebeurd dan wordt de executie van de generator hervat.

Wanneer de generator geheel uitgevoerd is, wordt de lus niet meer uitgevoerd aangezien er geen waarden meer zijn. In dit voorbeeld blijft de generator telkens getallen teruggeven waardoor men in de lus moet bepalen wanneer men klaar is. Zodra de executie van de lus wordt beëindigd, is de generator niet meer nodig voor het genereren van waarden.

Generatorexpressie bewerken

In Python zijn ook generatorexpressies aanwezig waarmee generatoren genoteerd kunnen worden in de vorm van een expressie. Deze generatorexpressies kunnen alleen for-lussen en if-statements bevatten.

Een voorbeeld van een generatorexpressie waarmee alle getallen onder de 1000 die deelbaar zijn door drie gegenereerd kunnen worden:

g = (n for n in range(1000) if n % 3 == 0)

g is nu een generator die op dezelfde manier gebruikt kan worden als even_getallen in het vorige voorbeeld.

De bovenstaande generatorexpressie kan ook genoteerd worden als:

def g():
    for n in range(1000):
        if n % 3 == 0:
            yield n

Haskell bewerken

In lijstcomprehensies in Haskell worden ook generatoren gebruikt. In dit geval betreft het lijsten waar telkens waarden uit opgeleverd worden in een lijstcomprehensie.

Een voorbeeld van een lijstcomprehensie:

[ 2 * x | x <- [0..], x * x > 10 ]

Hier is x <- [0..] een generator: x neemt telkens een (volgende) waarde aan uit de lijst [0..].