yield

Das Konzept hinter dem Schlüsselwort "yield" ist ebenso reizvoll und elegant wie auf den ersten Blick kompliziert. Es ist nicht unverzichtbar, macht aber viele Dinge angenehmer zu schreiben und schneller auszuführen.

Die folgende, zugegeben etwas unnütze Funktion überprüft für jedes Element der als erstes Argument übergebenen Liste, ob es sich in einen Integer umwandeln lässt. Alle Elemente auf die dieses Kriterium zutrifft, werden in einer Liste zurückgegeben:

def bsp_func(liste):
elemente = []
for element in liste:
try:
elemente.append(int(element))
except ValueError:
pass
return elemente

Über den Rückgabewert dieser Funktion würde man in vielen Fällen in einem Programm wie folgt iterieren:

for e in bsp_func(['foo', 'bar', '32', '23', 'sieben', 'drei', 32, 23, 42]):
print e

Mit "yield" lässt sich die Beispielfunktion etwas verändern. Statt die Funktion komplett zu durchlaufen und über ihren Rückgabewert, eine Liste, zu iterieren, wird mit "yield" ein Generator erzeugt, der nach und nach Elemente ausspuckt, und über diesen iteriert. Praktisch fühlt sich das so an, als würde die Funktion immer schrittweise bis zum nächsten "yield" ausgeführt werden. Das Argument zu "yield" wird dann als das "nächste Element" des Generators zurückgegeben, solange, bis die Funktion ihr Ende erreicht, keine weiteren Elemente mehr generiert werden und die Iteration endet:

def bsp_func(liste):
for element in liste:
try:
yield int(element)
except ValueError:
pass

Bei der eigendlichen for-Schleife in der Anwendung bedarf es keiner Änderung - hier verhält sich ein von "yield" erzeugter Generator genauso wie ein Iterator oder eine Liste. Der Generator bringt jedoch den Vorteil, dass hier nicht alle Elemente berechnet werden müssen, bevor die for-Schleife anfängt, die zurückgegebene Liste abzuarbeiten. Das spart neben ein paar Codezeilen in manchen Fällen Rechenzeit (wenn nicht alle Elemente durchlaufen werden) und im Regelfall Arbeitsspeicher, weil nicht alle Elemente gleichzeitig im RAM gehalten werden müssen.

Tags: Python