Was ist Iteration?
Objekte, die direkt in for-Schleifen verwendet werden können, werden zusammenfassend als iterierbare Objekte (Iterable) bezeichnet.
Ein Objekt, das von der Funktion next() aufgerufen werden kann und kontinuierlich den nächsten Wert zurückgibt, wird als Iterator bezeichnet.
Alle Iterables können über die integrierte Funktion iter() in Iteratoren umgewandelt werden.
Für Iteratoren reicht ein __next__(). Wenn Sie die for- und in-Anweisungen verwenden, ruft das Programm automatisch das Iteratorobjekt des zu verarbeitenden Objekts auf und verwendet dann seine Methode __next__(), bis eine StopIteration-Ausnahme erkannt wird.
>>> L = [1,2,3]
>>> [x**2 für x in L]
[1, 4, 9]
>>> next(L)
Traceback (letzter Aufruf zuletzt):
Datei „
TypeError: 'list ' Objekt ist kein Iterator
>>> I=iter(L)
>>> next(I)
>>> )
2
>>> next(I)
3
>>> next(I)
Traceback (letzter Anruf zuletzt):
Datei „
StopIteration
L wird von Iter gepackt und auf I gesetzt. I kann von next() verwendet werden, um den nächsten Wert zu finden, also ist I ein Iterator.
>>> I = L.__iter__()
>>> )
Traceback (letzter Aufruf zuletzt):
Datei „
AttributeError: „list“-Objekt hat kein Attribut „__next__“
> ;>> I.__next_()
4
>>> >>>> isinstance(L, Iterator)
False
>>> isinstance(I, Iterable)
True
>>> )
True
>>> [x**2 für x in I]
[25, 36]
Iterator erbt von Iterable, aus dem folgenden Test Es ist leicht zu erkennen, dass Iterator die Methoden __iter__() und __next__() enthält, während Iteratble nur __iter__() enthält.
>>> aus Sammlungen importieren Iterator, Iterable
Hilfe zum Klassen-Iterator:
Klasse Iterator(Iterable)
|. Reihenfolge der Methodenauflösung:
|. Iterable
|**Hinweis: Hier ist zu erkennen, dass Iterable von Objekt erbt und Iterator von Iterable .
|. Hier definierte Methoden:
|
|. __iter__(self)
| 🎜>......
>>> help(Iterable)
Hilfe zur Klasse Iterable:
class Iterable(builtins.object)
|.
|
|. __iter__(self)
......
iterable muss die Methode __iter__() enthalten, um den Iterator zurückzugeben, und der Iterator muss _ enthalten Die Methode _next__() wird zum Schleifen verwendet.
Wenn wir den Iterator selbst definieren, reicht es aus, eine Funktion __iter__() in der Klasse zu definieren und sie zu verwenden, um ein Objekt mit der Methode __next__() zurückzugeben.
Gehe direkt zum Code
class Iterable:
def __iter__(self):
return Iterator()
class Iterator:
def __init__(self) : self.start=-1
def __next__(self):
if self.start >10:
raise StopIteration
return self. start
I = Iterable()
für i in I: PRint(i)
Der obige Code dient dazu, ungerade Zahlen innerhalb von 10 zu finden. Der Klassenname im Code kann zufällig ausgewählt werden. Es ist nicht erforderlich, den oben angegebenen Klassennamen zu verwenden.
Wenn die StopIteration-Ausnahme nicht in der __next__-Methode von Iterator implementiert ist, dann werden alle ungeraden Zahlen dargestellt, dann müssen beim Aufruf die Bedingungen zum Verlassen der Schleife festgelegt werden.
class Iterable:
def __iter__(self):
return Iterator()
class Iterator:
def __init__(self):
self.start= -1
def __next__(self):
self.start +=2
return self.start
I = Iterable()
for count, i in zip(range( 5),I): #Sie können auch die integrierte Funktion enumerate verwenden, um Zählarbeiten zu implementieren.
print(i)
Wir verwenden den Bereich, um zu erkennen, wie viele Elemente gedruckt werden sollen. Hier bedeutet dies, dass 5 Elemente gedruckt werden, und das Rückgabeergebnis stimmt mit dem oben Gesagten überein.
Natürlich können wir diese beiden Klassen zusammenführen, um das Programm zu vereinfachen.
Die endgültige Version lautet wie folgt:
class Iterable:
def __iter__(self):
return self
def __init__(self):
self.start=-1
def __next__(self):
self.start +=2
if self.start >10:
StopIteration erhöhen
return self.start
I = Iterable ()
für i in I:
print(i)
Iterator kopieren
Iterator ist ein einmaliges Verbrauchsmaterial und wird nach Gebrauch leer sein, siehe .
>>> L=[1,2,3]
>>> für i in I:
... print(i, end='-')
...
1-2-3-
>>>next(I)
Traceback (most letzter Aufruf zuletzt):
Datei „
StopIteration
Aber wie Sie anhand des Beispiels unten sehen können, funktioniert es überhaupt nicht.
>>> J=I
>>> next(I)
>>> next(J)
2
>>> next(I)
>>> next(J)
Traceback (most letzter Aufruf zuletzt):
Datei „
StopIteration
Wie können wir also den gewünschten Effekt erzielen?
Wir müssen Deepcopy im Kopierpaket verwenden, siehe unten:
>>> import copy
>>> ;>> J=copy.deepcopy(I)
>>> next(I)
>>> next(J)
1
Ergänzung: Der Iterator kann sich nicht rückwärts bewegen oder zum Anfang zurückkehren.
Es muss also etwas Besonderes getan werden, um Funktionen wie die Rückwärtsbewegung zu erreichen.
Die oben genannten Codes wurden in Python 3.4 getestet.