Kapitel 7
Sequenzen, Mengen und Generatoren
222
Ihnen aufgefallen, dass es sich um Quadratzahlen handelt. Abstrakt könnte man diese Liste
auch so definieren:
Die Folge aller ganzen Quadratzahlen, die kleiner als 100 sind.
Damit ist diese Sequenz exakt festgelegt, obwohl kein einziges Element explizit genannt
wird. Genau das ist die Idee von Generatoren. Ein Generator ist eine virtuelle Kollektion von
Objekten, bei der die Objekte nicht explizit aufgezählt werden. Stattdessen wird eine Kon-
struktionsvorschrift angegeben, mit der bei Bedarf jedes Element generiert werden kann.
Generatoren können auf zweierlei Weise definiert werden: mit Generatorausdrücken oder
mit Generatorfunktionen.
7.5.1 Generatorausdrücke
Generatorausdrücke werden so wie list comprehensions gebildet (Abschnitt 7.4.1). Man ver-
wendet einfach nur runde anstelle von eckigen Klammern. Die oben beschriebene Liste von
Quadratzahlen können Sie folgendermaßen mit einem Generatorausdruck definieren:
Die Zeile kann man so lesen: Berechne für alle natürlichen Zahlen von 0 bis 9 das Quadrat
und bilde daraus eine (virtuelle) Folge. Im Unterschied zu einer Liste kann man den
»Inhalt« des Generators, d.h. die von ihm repräsentierte Kollektion, nicht so einfach ausge-
ben, sondern muss die Elemente in einer Iteration (
for-Schleife) einzeln abrufen.
7.5.2 Generatorfunktionen
Generatorfunktionen sind Funktionen, in denen ein yield-Statement vorkommt. Eine
Generatorfunktion gibt ein Generator-Objekt zurück. Die folgende Generatorfunktion lie-
fert einen Generator für Quadratzahlen von
0 bis n –1.
Testen wir zunächst einmal die Generatorfunktion und erzeugen mit ihr ein Generator-
Objekt.
>>> g = (i*i for i in range(10))
>>> print(g)
<generator object <genexpr> at 0x021B6D78>
>>> for n in g:
print(n, end= " ")
0 1 4 9 16 25 36 49 64 81
>>> def generiereZahlen(n):
for i in range(n):
yield i*i
>>> g = generiereZahlen(10)
>>> print(g)
<generator object generiereZahlen at 0x021BD5A8>
223
7.5
Generatoren
Nun zurück zur Funktionsdefinition. Welche Bedeutung hat das yield? Wenn der Python-
Interpreter bei der Ausführung der Generatorfunktion auf eine
yield-Anweisung stößt,
gibt er den Wert des Ausdrucks hinter
yield zurück, unterbricht dann die Ausführung und
merkt sich den aktuellen Zustand des zur Funktion gehörenden Prozesses. Erst wenn das
nächste Element des Generator-Objektes verlangt wird, wird die Ausführung der Funktion
fortgesetzt. Im Unterschied zu einer Liste kann man die Elemente eines Generators nicht
beliebig lesen, sondern nur vorne beginnend in der vorgegebenen Reihenfolge. Die Stan-
dardfunktion
next() liefert das nächste Element der vom Generator erzeugten Folge.
Beispiel:
Das Objekt
g ist ein Generator-Objekt, das von der Generatorfunktion generiereZahlen()
erzeugt worden ist.
Das ist das erste Element der Folge. Um in der IDLE-Shell den gleichen Befehl nochmals
abzusetzen, drücken Sie die Tastenkombination
(Alt)+(p).
>>> for i in g:
print(i, end= " ")
0 1 4 9 16 25 36 49 64 81
>>> def generiereZahlen(n):
i = 1
while i <= n:
yield i*i
i += 1
>>> g = generiereZahlen(3)
>>> g
<generator object at 0x00A958C8>
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
Traceback (most recent call last):
File "<pyshell#27>", line 1, in <module>
next(g)
StopIteration

Get Python 3 - Lernen und professionell anwenden now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.