Python Iteratoren meistern: Funktionsweise und Erstellung eigener Iteratoren
Python Iteratoren
Entdecken Sie, wie Python-Iteratoren funktionieren, wie man sie mit for-Schleifen oder der next()-Funktion durchläuft und wie man benutzerdefinierte oder unendliche Iteratoren mit dem Iterator-Protokoll erstellt.
Video: Python Iteratoren
Iteratoren in Python
Iteratoren sind allgegenwärtig in Python. Sie liegen for-Schleifen, List Comprehensions, Generatoren und vielen eingebauten Datenstrukturen zugrunde und arbeiten oft hinter den Kulissen.
Ein Iterator ist einfach ein Objekt, das Daten ein Element nach dem anderen liefert. In Python wird jedes Objekt, das die __iter__()- und __next__()-Methoden implementiert, als Iterator betrachtet.
Wenn ein Objekt einen Iterator bereitstellen kann, heißt es iterierbar. Die meisten eingebauten Container – Listen, Tupel, Strings, Dictionaries – sind iterierbar. Die eingebaute iter()-Funktion ruft die __iter__()-Methode eines Objekts auf, um einen Iterator zu erhalten.
Durch einen Iterator iterieren
Sie können einen Iterator manuell mit der next()-Funktion voranbringen. Sobald der Iterator erschöpft ist, wird StopIteration ausgelöst.
# Liste definieren
meine_liste = [4, 7, 0, 3]
# Iterator mit iter() erhalten
mein_iter = iter(meine_liste)
# Mit next() durchlaufen
# Ausgabe: 4
print(next(mein_iter))
# Ausgabe: 7
print(next(mein_iter))
# next(obj) ist dasselbe wie obj.__next__()
# Ausgabe: 0
print(mein_iter.__next__())
# Ausgabe: 3
print(mein_iter.__next__())
# Dies löst Fehler aus, keine Elemente mehr
next(mein_iter)
Ausgabe
4 7 0 3 Traceback (most recent call last): File "<string>", line 24, in <module> next(mein_iter) StopIteration
Eine natürlichere Art zu iterieren ist die Verwendung einer for-Schleife, die den Iterator-Lebenszyklus automatisch handhabt.
>>> for element in meine_liste:
... print(element)
... 4 7 0 3
Wie die for-Schleife mit Iteratoren funktioniert
Die for-Schleife übersetzt intern zu:
for element in iterierbar:
# etwas mit element tun
was äquivalent zur folgenden Logik ist:
# Iterator-Objekt aus dem Iterierbaren erstellen
iter_obj = iter(iterierbar)
# endlose Schleife
while True:
try:
# nächstes Element holen
element = next(iter_obj)
# etwas mit element tun
except StopIteration:
# wenn StopIteration ausgelöst wird, aus Schleife ausbrechen
break
Dies zeigt, dass die for-Schleife im Wesentlichen eine endlose Schleife ist, die sich auf das Iterator-Protokoll und die StopIteration-Exception zur Beendigung verlässt.
Benutzerdefinierte Iteratoren erstellen
Einen Iterator von Grund auf zu erstellen ist unkompliziert: Implementieren Sie __iter__(), um die Iterator-Instanz (oft self) zurückzugeben, und __next__(), um den nächsten Wert zu liefern oder StopIteration auszulösen, wenn fertig.
Unten ist ein Beispiel, das aufeinanderfolgende Zweierpotenzen bis zu einem benutzerdefinierten maximalen Exponenten liefert.
class PotenzZwei:
"""Iterator, der Zweierpotenzen liefert."""
def __init__(self, max=0):
self.max = max
def __iter__(self):
self.n = 0
return self
def __next__(self):
if self.n <= self.max:
result = 2 ** self.n
self.n += 1
return result
else:
raise StopIteration
# Objekt erstellen
zahlen = PotenzZwei(3)
# Iterable aus dem Objekt erstellen
i = iter(zahlen)
# Mit next zum nächsten Iterator-Element gelangen
print(next(i))
print(next(i))
print(next(i))
print(next(i))
print(next(i))
Ausgabe
1 2 4 8 Traceback (most recent call last): File "/home/bsoyuj/Desktop/Untitled-1.py", line 32, in <module> print(next(i)) File "<string>", line 18, in __next__ raise StopIteration StopIteration
Die Verwendung einer for-Schleife mit dem benutzerdefinierten Iterator ist ebenso einfach:
>>> for i in PotenzZwei(5):
... print(i)
... 1 2 4 8 16 32
Python unendliche Iteratoren
Iteratoren können unbegrenzt sein. Die eingebaute iter() akzeptiert einen Callable und einen Sentinel-Wert: Sie ruft die Funktion wiederholt auf, bis der Rückgabewert dem Sentinel entspricht. Zum Beispiel:
>>> int()
0
>>> inf = iter(int, 1)
>>> next(inf)
0
>>> next(inf)
0
Da int() immer 0 zurückgibt, sieht iter(int, 1) niemals den Sentinel und produziert einen unendlichen Iterator.
Sie können auch Ihren eigenen unendlichen Iterator erstellen, wie einen, der alle ungeraden Zahlen liefert:
class UnendlicherIter:
"""Unendlicher Iterator, der aufeinanderfolgende ungerade Zahlen liefert."""
def __iter__(self):
self.num = 1
return self
def __next__(self):
num = self.num
self.num += 2
return num
Beispielausführung:
>>> a = iter(UnendlicherIter())
>>> next(a)
1
>>> next(a)
3
>>> next(a)
5
>>> next(a)
7
Bei der Arbeit mit unendlichen Iteratoren immer eine Abbruchbedingung vorsehen, um endlose Schleifen zu vermeiden.
Iteratoren sind speichereffizient, da sie Elemente auf Abruf produzieren. Sie können theoretisch eine unbegrenzte Sequenz erzeugen – wie alle ungeraden Zahlen – ohne die gesamte Menge zu speichern.
Für eine einfachere Möglichkeit, Iteratoren zu erstellen, erkunden Sie Python Generatoren mit yield.
Python
- Python-Datentypen meistern: Praxisleitfaden
- Python-Operatoren meistern: Umfassender Leitfaden
- Python pass-Statement meistern: Praxisleitfaden
- Python-Funktionsargumente meistern: Positional, Keyword & Default-Parameter
- Python-Dictionaries meistern: Erstellung, Manipulation und fortgeschrittene Techniken
- Python Closures erklärt: Wie verschachtelte Funktionen Variablen erfassen
- Python datetime meistern: Praktischer Leitfaden zu Datumsangaben, Zeiten und Zeitzonen
- Pythons time.sleep() meistern: Best Practices, Multithreading und Praxisbeispiele
- Python Überblick: Hochlevel, lesbar, interaktiv & objektorientiert
- Python Zahlen: Unveränderliche numerische Datentypen verstehen