Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
modul:m323:learningunits:lu04:generatoren [2025/12/18 13:20] – kmaurizimodul:m323:learningunits:lu04:generatoren [2026/09/01 11:16] (aktuell) – Animation zu Lazy Evaluation und yield eingebettet admin
Zeile 6: Zeile 6:
  
 Ein Generator ist ein spezieller Typ von Iterator, der mit einer Funktion und dem Schlüsselwort ''yield'' erstellt wird. Im Gegensatz zu normalen Funktionen, die einen Wert zurückgeben und dann beendet werden, "pausieren" Generatoren ihren Zustand und setzen die Ausführung fort, wenn der nächste Wert benötigt wird. Ein Generator ist ein spezieller Typ von Iterator, der mit einer Funktion und dem Schlüsselwort ''yield'' erstellt wird. Im Gegensatz zu normalen Funktionen, die einen Wert zurückgeben und dann beendet werden, "pausieren" Generatoren ihren Zustand und setzen die Ausführung fort, wenn der nächste Wert benötigt wird.
 +
 +===== Wichtige Eigenschaften =====
 +
 +  * **Lazy**: Werte werden erst erzeugt, wenn sie gebraucht werden (z.B. im ''for''-Loop oder mit ''next()'').
 +  * **Einmal konsumierbar**: Ein Generator läuft von vorne nach hinten durch. Was "verbraucht" ist, ist weg.
 +  * **Zustand bleibt erhalten**: Lokale Variablen behalten ihren Wert zwischen zwei ''yield''-Schritten.
 +
 +===== Animation: wann wird eigentlich gerechnet? =====
 +
 +Diese drei Eigenschaften sind im Code nicht sichtbar – die Animation macht sie sichtbar. Der erste Tab zeigt, dass der Aufruf einer Generator-Funktion **keine einzige Zeile** ausführt, wo ''yield'' anhält und was dabei stehen bleibt. Der zweite Tab vergleicht Generator Expression und List Comprehension und zeigt, warum ein zweites ''sum()'' auf demselben Generator stillschweigend ''0'' ergibt.
 +
 +{{url>https://templates-python.github.io/m323_html/lu04/generatoren.html 100%,900px noborder|Animation: Generatoren, wann wird eigentlich gerechnet?}}
  
 ===== Syntax ===== ===== Syntax =====
Zeile 16: Zeile 28:
     yield 2     yield 2
     yield 3     yield 3
 +</code>
 +
 +===== Generator vs. normale Funktion =====
 +
 +Eine normale Funktion liefert genau einen Rückgabewert und endet. Ein Generator liefert mehrere Werte nacheinander:
 +
 +<code python>
 +def normal_function():
 +    return 1
 +    return 2  # wird nie erreicht
 +
 +def generator_function():
 +    yield 1
 +    yield 2  # wird erreicht, wenn weiter iteriert wird
 +
 +print(normal_function())        # 1
 +gen = generator_function()
 +print(next(gen))                # 1
 +print(next(gen))                # 2
 </code> </code>
  
 ===== Beispiele ===== ===== Beispiele =====
  
-=== Einfacher Generator ===+==== Einfacher Generator ====
  
 Ein einfacher Generator, der die Zahlen 1 bis 3 zurückgibt: Ein einfacher Generator, der die Zahlen 1 bis 3 zurückgibt:
Zeile 31: Zeile 62:
  
 gen = simple_generator() gen = simple_generator()
-print(next(gen))  # Output: 1 +print(next(gen))  # 1 
-print(next(gen))  # Output: 2 +print(next(gen))  # 2 
-print(next(gen))  # Output: 3+print(next(gen))  # 3
 </code> </code>
  
-=== Generator mit Schleife ===+==== Generator mit Schleife ====
  
 Ein Generator, der die Quadrate der Zahlen von 1 bis n zurückgibt: Ein Generator, der die Quadrate der Zahlen von 1 bis n zurückgibt:
Zeile 42: Zeile 73:
 <code python> <code python>
 def square_numbers(n): def square_numbers(n):
-    for i in range(1, n+1):+    for i in range(1, n + 1):
         yield i * i         yield i * i
  
Zeile 53: Zeile 84:
 </code> </code>
  
-=== Generator Expression ===+==== Generator Expression ====
  
 Generator Expressions sind eine kompaktere Art, Generatoren zu erstellen, ähnlich wie List Comprehensions: Generator Expressions sind eine kompaktere Art, Generatoren zu erstellen, ähnlich wie List Comprehensions:
  
 <code python> <code python>
-squared = (x*x for x in range(6)) +squared = (x * x for x in range(6)) 
-print(next(squared))  # Output: 0 +print(next(squared))  # 0 
-print(next(squared))  # Output: 1+print(next(squared))  # 1 
 +</code> 
 + 
 +===== Typische Verwendung: for-Loop statt next() ===== 
 + 
 +In der Praxis nutzt man Generatoren meistens im ''for''-Loop, weil der Loop automatisch stoppt, wenn der Generator fertig ist: 
 + 
 +<code python> 
 +def countdown(n): 
 +    while n > 0: 
 +        yield n 
 +        n -= 1 
 + 
 +for value in countdown(3): 
 +    print(value) 
 + 
 +# Output: 
 +# 3 
 +# 2 
 +# 1 
 +</code> 
 + 
 +===== StopIteration: Was passiert, wenn der Generator fertig ist? ===== 
 + 
 +Wenn ein Generator keine Werte mehr liefern kann, endet er. Bei ''next()'' führt das zu einer Exception ''StopIteration'': 
 + 
 +<code python> 
 +gen = (x for x in range(2)) 
 +print(next(gen))  # 0 
 +print(next(gen))  # 1 
 + 
 +# nächster Aufruf -> StopIteration 
 +# print(next(gen)) 
 +</code> 
 + 
 +===== Generatoren sind Iteratoren ===== 
 + 
 +Ein Generator ist selbst ein Iterator: ''iter(gen)'' gibt den Generator zurück, und ''next(gen)'' liefert den nächsten Wert. 
 + 
 +<code python> 
 +gen = (x for x in range(3)) 
 +print(iter(gen) is gen)  # True
 </code> </code>
  
Zeile 68: Zeile 140:
   * **Einfachheit**: Generatoren sind einfacher zu implementieren als benutzerdefinierte Iteratoren.   * **Einfachheit**: Generatoren sind einfacher zu implementieren als benutzerdefinierte Iteratoren.
   * **Vielseitigkeit**: Generatoren können für jede Art von Datenquelle verwendet werden, nicht nur für Listen oder Sequenzen.   * **Vielseitigkeit**: Generatoren können für jede Art von Datenquelle verwendet werden, nicht nur für Listen oder Sequenzen.
 +  * **Abbruch möglich**: Man kann früh aufhören zu iterieren (z.B. nach dem ersten Treffer). Der Rest wird gar nie berechnet.
  
 ===== Verständnis des ''yield''-Schlüsselworts ===== ===== Verständnis des ''yield''-Schlüsselworts =====
  
-Das Schlüsselwort ''yield'' in Python wird verwendet, um einen Wert aus einer Funktion zurückzugeben und den aktuellen Zustand der Funktion zu speichern. Wenn die Funktion das nächste Mal aufgerufen wird, wird sie von der Stelle fortgesetzt, an der sie zuletzt angehalten wurde, und nicht von Anfang an. Dies ermöglicht es der Funktion, Werte "on-the-fly" zu generieren, ohne den gesamten Datensatz im Speicher zu halten.+Das Schlüsselwort ''yield'' in Python wird verwendet, um einen Wert aus einer Funktion zurückzugeben und den aktuellen Zustand der Funktion zu speichern. Wenn die Funktion das nächste Mal weiter iteriert wird, wird sie von der Stelle fortgesetzt, an der sie zuletzt angehalten wurde, und nicht von Anfang an. 
 + 
 +===== Mini-Zusammenfassung ===== 
 + 
 +^ Begriff ^ Bedeutung ^ 
 +| ''yield'' | Liefert einen Wert und pausiert die Funktion (Zustand bleibt erhalten). | 
 +| Generator | Iterator, der Werte "lazy" erzeugt. | 
 +| ''next(gen)'' | Liefert den nächsten Wert (oder ''StopIteration'', wenn fertig). | 
 +| Generator Expression | Kurzform: ''(expression for item in iterable if condition)'' |
  
 ---- ----
-{{tag>M323-LU04}} +{{tag>M323-LU04 M323-D1B}} 
-[[https://creativecommons.org/licenses/by-nc-sa/4.0/ch/|{{https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png}}]] (c) Kevin Maurizi +[[https://creativecommons.org/licenses/by-nc-sa/4.0/ch/|{{https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png}}]] (c) Kevin Maurizi
  
  • modul/m323/learningunits/lu04/generatoren.1766060409.txt.gz
  • Zuletzt geändert: 2025/12/18 13:20
  • von kmaurizi