Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
| Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung Nächste Überarbeitung | Vorherige Überarbeitung | ||
| talit:generators [2024-05-06 13:35] – [Iterables] hof | talit:generators [2025-08-15 07:36] (aktuell) – [Aufgabe 4: Pre-Order Traversierung] hof | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| # Iteratoren und Generatoren in Python | # Iteratoren und Generatoren in Python | ||
| + | < | ||
| + | |||
| Eine [[wpde> | Eine [[wpde> | ||
| Zeile 9: | Zeile 11: | ||
| ### Aufgabe 1: Fibonacci-Liste | ### Aufgabe 1: Fibonacci-Liste | ||
| - | Unser erster Versuch: Schreibe eine Funktion, die die ersten `n` Elemente der Fibonacci-Folge generiert und in einer Liste zurückgibt. | + | Unser erster Versuch: Schreibe eine Funktion, die die ersten `n` Elemente der Fibonacci-Folge generiert und in einer Liste zurückgibt. |
| - | <nodisp | + | <html>< |
| + | first_few = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] | ||
| + | result = [] | ||
| + | for i in range(n): | ||
| + | result.append(first_few[i]) | ||
| + | return result | ||
| + | |||
| + | print(fibonacci(10))</ | ||
| + | |||
| + | <nodisp 0> | ||
| ++++Lösung| | ++++Lösung| | ||
| - | <html><iframe frameborder=" | + | <code python> |
| - | "></iframe></ | + | def fibonacci(n=10): |
| + | result | ||
| + | one = 0 | ||
| + | | ||
| + | | ||
| + | # Python erlaubt Zuweisungen von Tupeln - | ||
| + | # natürlich lässt sich die Zuweisung auch auf | ||
| + | # mehrere Zeilen verteilen. | ||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | print(fibonacci(10)) | ||
| + | </code> | ||
| ++++ | ++++ | ||
| </ | </ | ||
| - | Das Problem ist nur, dass die Liste viel Speicher | + | Das Problem ist nur, dass die Liste viel Speicher |
| - | Natürlich könnten wir für beide Probleme eine eigene, effiziente Funktion schreiben, die ohne Liste auskommt - aber als faule Informatiker möchten wir es vermeiden, den gleichen Code zweimal zu schreiben... | + | Natürlich könnten wir für beide Probleme eine eigene, effiziente Funktion schreiben, die ohne Liste auskommt - aber als faule Informatiker: |
| Gesucht ist also ein Stück Code, das einen _Strom_ von Fibonacci-Zahlen liefert, die wir kontinuierlich konsumieren können, bis wir genug haben. | Gesucht ist also ein Stück Code, das einen _Strom_ von Fibonacci-Zahlen liefert, die wir kontinuierlich konsumieren können, bis wir genug haben. | ||
| Zeile 26: | Zeile 50: | ||
| ## Iteratoren | ## Iteratoren | ||
| - | Soche Strom-Objekte heissten _Iteratoren_. Ein Iterator hat nur eine einzige Funktion, `__next__`, die jeweils das nächste Element zurückgibt. Der Iterator muss sich irgendwie den Zustand merken, also wo in der Fibonacci-Folge er gerade steckt. Die Funktion wirft eine `StopIteration` Exception wenn es keine weiteren Elemente gibt. | + | Solche |
| + | |||
| + | Die _built-in function_ [next](https:// | ||
| - | Die built-in function [next](https:// | ||
| ### Aufgabe 2: Fibonacci-Iterator | ### Aufgabe 2: Fibonacci-Iterator | ||
| Analysiere den untenstehenden Code und führe ihn aus. Ändere den Code, so dass die erste Fibonacci Zahl ausgegeben wird, die grösser als 1000 ist! | Analysiere den untenstehenden Code und führe ihn aus. Ändere den Code, so dass die erste Fibonacci Zahl ausgegeben wird, die grösser als 1000 ist! | ||
| - | < | + | < |
| - | "></iframe></ | + | |
| + | # Constructor - hier wird der Initial-Zustand gespeichert | ||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | iterator = FiboIterator() | ||
| + | print(next(iterator)) | ||
| + | print(next(iterator)) | ||
| + | print(next(iterator))</bottom-editor></ | ||
| - | < | + | < |
| ++++Lösung| | ++++Lösung| | ||
| <code python> | <code python> | ||
| Zeile 49: | Zeile 92: | ||
| ++++ | ++++ | ||
| </ | </ | ||
| + | |||
| ## Iterables | ## Iterables | ||
| Zeile 68: | Zeile 112: | ||
| Untenstehender Code fügt dem bestehenden Iterator ein Iterable hinzu, so dass wir eine for-Schleife nützen können: | Untenstehender Code fügt dem bestehenden Iterator ein Iterable hinzu, so dass wir eine for-Schleife nützen können: | ||
| - | < | + | < |
| - | "></iframe></ | + | |
| + | # Hier wird der Zustand gespeichert | ||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | class FiboIterable: | ||
| + | # Wird einmal aufgerufen, wenn Python die for-Schleife startet. | ||
| + | | ||
| + | | ||
| + | |||
| + | sequence = FiboIterable() | ||
| + | for num in sequence: | ||
| + | | ||
| + | | ||
| + | | ||
| + | </bottom-editor></ | ||
| + | |||
| + | Die Funktionen `__iter__` und `__next__` dürfen auch von derselben Klasse implementiert werden. | ||
| - | Die Funktionen `__iter__` und `__next__` dürfen auch von derselben Klasse implementiert werden | ||
| - | . | ||
| ## Yield | ## Yield | ||
| Zeile 81: | Zeile 149: | ||
| Ein Generator ist ein Iterable und kann damit auch als Ausdruck nach `in` in einer `for ... in < | Ein Generator ist ein Iterable und kann damit auch als Ausdruck nach `in` in einer `for ... in < | ||
| - | < | + | < |
| - | "></iframe></ | + | |
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | for num in fibo(): | ||
| + | | ||
| + | | ||
| + | | ||
| + | </bottom-editor></ | ||
| ### Iteration beenden | ### Iteration beenden | ||
| Sind keine Elemente mehr übrig, wird einfach nichts zurückgegeben bzw. ein normales `return`. | Sind keine Elemente mehr übrig, wird einfach nichts zurückgegeben bzw. ein normales `return`. | ||
| - | #### Aufgabe 3: Limitieren | + | ### Aufgabe 3: Limitieren |
| Verändere den obigen Code um ein optionales Limit einzubauen, wieviele Elemente erzeugt werden sollen. | Verändere den obigen Code um ein optionales Limit einzubauen, wieviele Elemente erzeugt werden sollen. | ||
| Zeile 93: | Zeile 171: | ||
| Der folgende Code soll also `143` ausgeben: | Der folgende Code soll also `143` ausgeben: | ||
| - | < | + | < |
| - | "></iframe></ | + | |
| + | |||
| + | n=10 | ||
| + | print(f' | ||
| + | </bottom-editor></ | ||
| ## Yield From | ## Yield From | ||
| Manchmal möchten wir eine andere Iteration (bzw. einen anderen Generator) in die gerade laufende Iteration einbinden. Dazu dienen die Keywords `yield from`. | Manchmal möchten wir eine andere Iteration (bzw. einen anderen Generator) in die gerade laufende Iteration einbinden. Dazu dienen die Keywords `yield from`. | ||
| Zeile 100: | Zeile 183: | ||
| Beispiel: ein einfacher Binärbaum besteht aus Knoten (_en_: Nodes), die jeweils bis zu zwei Kinder haben können. | Beispiel: ein einfacher Binärbaum besteht aus Knoten (_en_: Nodes), die jeweils bis zu zwei Kinder haben können. | ||
| - | {{:talit: | + | [[https:// |
| Um den Baum zu traversieren (d.h. alle Knoten zu besuchen), können wir zum Beispiel die [[wpde> | Um den Baum zu traversieren (d.h. alle Knoten zu besuchen), können wir zum Beispiel die [[wpde> | ||
| Zeile 106: | Zeile 189: | ||
| Eine rekursive Umsetzung könnte wie folgt aussehen - beachte, wie `yield from` eingesetzt wird, um die rekursive Traversierung zu erreichen. | Eine rekursive Umsetzung könnte wie folgt aussehen - beachte, wie `yield from` eingesetzt wird, um die rekursive Traversierung zu erreichen. | ||
| - | < | + | < |
| - | "></iframe></ | + | |
| - | ### Aufgabe 4: In-Order Traversierung | + | |
| + | | ||
| + | | ||
| + | |||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | |||
| + | tree = Node(5, Node(2, Node(1), Node(3)), Node(7)) | ||
| + | |||
| + | for node in tree.in_order_traversal(): | ||
| + | </bottom-editor></ | ||
| + | ### Aufgabe 4: Pre-Order Traversierung | ||
| - | Füge eine Methode `pre_order_traversierung` hinzu, die zuerst jeweils den Knoten selbst, dann den linken und rechten Teilbaum besucht. Die Reihenfolge des Besuchs sollte also `5 1 7` ausgeben. | + | Füge eine Methode `pre_order_traversal` hinzu, die zuerst jeweils den Knoten selbst, dann den linken und rechten Teilbaum besucht. Die Reihenfolge des Besuchs sollte also `5 2 1 3 7` ausgeben. |
| ### Weiter? | ### Weiter? | ||
| Zurück zum [[talit: | Zurück zum [[talit: | ||