Berekeningen "op verzoek" of luie berekeningen zijn populair geworden met de toename van de verwerkte gegevensvolumes. In Python zijn dergelijke mechanismen gerealiseerd in de standaardbibliotheek via generatoren en iterators, later via de functie itertools en klassen die in staat zijn om één element per keer op aanvraag te retourneren, waardoor het opslaan van alle gegevens in het geheugen onmiddellijk wordt vermeden.
De gebruikelijke opbouw van collecties vereist dat het volledige resultaat in het geheugen wordt geladen. Als de hoeveelheid groot is, kan het programma "crashen" of zeer langzaam werken. Het is belangrijk om datastromen te kunnen verwerken — bijvoorbeeld bestanden van meerdere gigabytes of de resultaten van API-aanroepen.
Luie berekeningen maken het mogelijk om elementen naar behoefte te verkrijgen. In Python wordt dit vergemakkelijkt door het gebruik van generatoren, de yield-syntaxis, generator-expressies, de functies map, filter, zip, evenals de itertools-module. Deze benadering is gebaseerd op het iterator-protocol.
Voorbeeldcode:
def huge_sequence(): for i in range(1, 10**9): yield i * i for val in huge_sequence(): if val > 100: break print(val)
Belangrijkste kenmerken:
Leveren generatoren in Python altijd een geheugenbesparing op?
Antwoord: Nee, alleen als de gegevens daadwerkelijk geen tussentijdse opslag vereisen tussen de stappen. Sommige constructies, zoals list comprehensions, creëren de hele lijst tegelijkertijd, terwijl generatoren alleen op aanvraag genereren. Als tussentijdse resultaten toch nodig zijn, gaat de besparing verloren.
Voorbeeld:
squares = (x**2 for x in range(10**8)) # lui, economisch result = list(squares) # verbruikt onmiddellijk al het geheugen
Is het waar dat map en filter altijd lijsten retourneren?
Nee, in Python 3 retourneren map en filter geen lijst, maar een iterator (luie generator), wat geheugen bespaart en het mogelijk maakt om gegevens "on the fly" te verwerken.
Kan je meerdere keren door een generator itereren?
Nee, een generator "verbrandt" na een volledige iteratie. Als je een herhaalde doorgang nodig hebt, moet je een nieuwe generator aanmaken of een container-collectie gebruiken waarvan de inhoud meerdere keren kan worden doorlopen.
Een ontwikkelaar probeert een groot logbestand te verwerken door het in het geheugen te laden als een lijst van regels.
Voordelen:
Nadelen:
Een generator wordt gebruikt — regel-voor-regel lezing van een bestand met verwerking van elke regel na ontvangst.
Voordelen:
Nadelen: