Python-Iteratoren (__iter__ und __next__): Wie und warum?

Iteratoren sind Objekte, auf denen iteriert werden kann. In diesem Tutorial erfahren Sie, wie der Iterator funktioniert und wie Sie mit den Methoden __iter__ und __next__ Ihren eigenen Iterator erstellen können.

Video: Python-Iteratoren

Iteratoren in Python

Iteratoren sind überall in Python. Sie sind elegant in forSchleifen, Verständnis, Generatoren usw. implementiert , aber in der Öffentlichkeit verborgen.

Iterator in Python ist einfach ein Objekt, das iteriert werden kann. Ein Objekt, das Daten einzeln zurückgibt.

Technisch gesehen ist ein Python Iteratorobjekt müssen zwei spezielle Methoden implementieren, __iter__()und __next__(), gemeinsam das genannte Iterator - Protokoll .

Ein Objekt heißt iterable, wenn wir einen Iterator daraus erhalten können. Die meisten in Python integrierten Container wie: Liste, Tupel, Zeichenfolge usw. sind iterabel.

Die iter()Funktion (die wiederum die __iter__()Methode aufruft ) gibt einen Iterator von ihnen zurück.

Iterieren durch einen Iterator

Wir verwenden die next()Funktion, um alle Elemente eines Iterators manuell zu durchlaufen. Wenn wir das Ende erreichen und keine Daten mehr zurückgegeben werden müssen, wird die StopIterationAusnahme ausgelöst. Es folgt ein Beispiel.

 # define a list my_list = (4, 7, 0, 3) # get an iterator using iter() my_iter = iter(my_list) # iterate through it using next() # Output: 4 print(next(my_iter)) # Output: 7 print(next(my_iter)) # next(obj) is same as obj.__next__() # Output: 0 print(my_iter.__next__()) # Output: 3 print(my_iter.__next__()) # This will raise error, no items left next(my_iter)

Ausgabe

 4 7 0 3 Traceback (letzter Aufruf zuletzt): Datei "", Zeile 24, in next (my_iter) StopIteration

Eine elegantere Art der automatischen Iteration ist die Verwendung der for-Schleife. Auf diese Weise können wir jedes Objekt durchlaufen, das einen Iterator zurückgeben kann, z. B. Liste, Zeichenfolge, Datei usw.

 >>> for element in my_list:… print(element)… 4 7 0 3

Arbeiten der for-Schleife für Iteratoren

Wie wir im obigen Beispiel sehen, konnte die forSchleife die Liste automatisch durchlaufen.

Tatsächlich kann die forSchleife über jedes iterierbare Element iterieren. Schauen wir uns genauer an, wie die forSchleife tatsächlich in Python implementiert ist.

 for element in iterable: # do something with element

Ist eigentlich implementiert als.

 # create an iterator object from that iterable iter_obj = iter(iterable) # infinite loop while True: try: # get the next item element = next(iter_obj) # do something with element except StopIteration: # if StopIteration is raised, break from loop break

Intern erstellt die forSchleife also ein Iteratorobjekt, iter_objindem sie iter()das iterable aufruft .

Ironischerweise ist diese forSchleife tatsächlich eine Endlos-while-Schleife.

Innerhalb der Schleife ruft es next()auf, um das nächste Element abzurufen, und führt den Hauptteil der forSchleife mit diesem Wert aus. Nachdem alle Gegenstände abgesaugt sind, StopIterationwird angehoben, was intern gefangen wird und die Schleife endet. Beachten Sie, dass jede andere Art von Ausnahme durchlaufen wird.

Erstellen von benutzerdefinierten Iteratoren

Das Erstellen eines Iterators von Grund auf ist in Python einfach. Wir müssen nur die __iter__()und die __next__()Methoden implementieren .

Die __iter__()Methode gibt das Iteratorobjekt selbst zurück. Bei Bedarf kann eine Initialisierung durchgeführt werden.

Die __next__()Methode muss das nächste Element in der Sequenz zurückgeben. Bei Erreichen des Endes und bei nachfolgenden Anrufen muss es erhöht werden StopIteration.

Hier zeigen wir ein Beispiel, das uns die nächste Potenz von 2 in jeder Iteration gibt. Der Leistungsexponent beginnt bei Null bis zu einer vom Benutzer festgelegten Nummer.

Wenn Sie keine Ahnung von objektorientierter Programmierung haben, besuchen Sie Python Object-Oriented Programming.

 class PowTwo: """Class to implement an iterator of powers of two""" 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 # create an object numbers = PowTwo(3) # create an iterable from the object i = iter(numbers) # Using next to get to the next iterator element print(next(i)) print(next(i)) print(next(i)) print(next(i)) print(next(i))

Ausgabe

 1 2 4 8 Traceback (letzter Aufruf zuletzt): Datei "/home/bsoyuj/Desktop/Untitled-1.py", Zeile 32, in gedruckter (next (i)) Datei "", Zeile 18, in __next__ erhöhen StopIteration StopIteration

Wir können auch eine forSchleife verwenden, um über unsere Iteratorklasse zu iterieren.

 >>> for i in PowTwo(5):… print(i)… 1 2 4 8 16 32

Python Infinite Iterators

Es ist nicht erforderlich, dass das Element in einem Iteratorobjekt erschöpft ist. Es kann unendlich viele Iteratoren geben (die niemals enden). Wir müssen vorsichtig sein, wenn wir mit solchen Iteratoren umgehen.

Hier ist ein einfaches Beispiel, um unendliche Iteratoren zu demonstrieren.

The built-in function iter() function can be called with two arguments where the first argument must be a callable object (function) and second is the sentinel. The iterator calls this function until the returned value is equal to the sentinel.

 >>> int() 0 >>> inf = iter(int,1) >>> next(inf) 0 >>> next(inf) 0

We can see that the int() function always returns 0. So passing it as iter(int,1) will return an iterator that calls int() until the returned value equals 1. This never happens and we get an infinite iterator.

We can also build our own infinite iterators. The following iterator will, theoretically, return all the odd numbers.

 class InfIter: """Infinite iterator to return all odd numbers""" def __iter__(self): self.num = 1 return self def __next__(self): num = self.num self.num += 2 return num

A sample run would be as follows.

 >>> a = iter(InfIter()) >>> next(a) 1 >>> next(a) 3 >>> next(a) 5 >>> next(a) 7

And so on…

Be careful to include a terminating condition, when iterating over these types of infinite iterators.

Der Vorteil der Verwendung von Iteratoren besteht darin, dass sie Ressourcen sparen. Wie oben gezeigt, könnten wir alle ungeraden Zahlen erhalten, ohne das gesamte Zahlensystem im Speicher zu speichern. Wir können (theoretisch) unendlich viele Gegenstände im endlichen Gedächtnis haben.

Es gibt eine einfachere Möglichkeit, Iteratoren in Python zu erstellen. Weitere Informationen finden Sie unter: Python-Generatoren mit Ertrag.

Interessante Beiträge...