Ich studiere Alex Martelis Python auf den Punkt gebracht und das Buch schlägt vor, dass jedes Objekt, das eine next()
Methode hat, ein Iterator ist (oder zumindest als Iterator verwendet werden kann) . Es wird auch vorgeschlagen, dass die meisten Iteratoren durch implizite oder explizite Aufrufe einer aufgerufenen Methode erstellt werden iter
.
Nachdem ich dies in dem Buch gelesen hatte, verspürte ich den Drang, es zu versuchen. Ich habe einen Python 2.7.3-Interpreter gestartet und dies getan:
>>> x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> for number in range(0, 10):
... print x.next()
Das Ergebnis war jedoch folgendes:
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
AttributeError: 'list' object has no attribute 'next'
In Verwirrung versuchte ich, die Struktur des x-Objekts über zu untersuchen, dir(x)
und bemerkte, dass es ein __iter__
Funktionsobjekt hatte. Also habe ich herausgefunden, dass es als Iterator verwendet werden kann, solange es diese Art von Schnittstelle unterstützt.
Als ich es erneut versuchte, diesmal etwas anders, versuchte ich Folgendes:
>>> _temp_iter = next(x)
Ich habe diesen Fehler erhalten:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list object is not an iterator
Aber wie kann eine Liste KEIN Iterator sein, da sie diese Schnittstelle zu unterstützen scheint und im folgenden Kontext durchaus als eine verwendet werden kann:
>>> for number in x:
... print x
Könnte mir jemand helfen, dies in meinem Kopf zu klären?
next
kehren einfach zurückself
, sodass Sieiter(iter(iter(iter(x))))
das Gleiche wie aufrufen und abrufen könneniter(x)
. Aus diesem Grundfor
funktioniert es sowohl mit Iterables als auch mit Iteratoren ohne Typ-Sniffing (ohne Berücksichtigung von Leistungsoptimierungen).iter
einfach zurückself
".Sie müssen die Liste zuerst in einen Iterator konvertieren, indem Sie Folgendes verwenden
iter()
:In [7]: x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] In [8]: it=iter(x) In [9]: for i in range(10): it.next() ....: ....: Out[10]: 0 Out[10]: 1 Out[10]: 2 Out[10]: 3 Out[10]: 4 Out[10]: 5 Out[10]: 6 Out[10]: 7 Out[10]: 8 Out[10]: 9 In [12]: 'next' in dir(it) Out[12]: True In [13]: 'next' in dir(x) Out[13]: False
Überprüfen, ob ein Objekt ein Iterator ist oder nicht:
In [17]: isinstance(x,collections.Iterator) Out[17]: False In [18]: isinstance(x,collections.Iterable) Out[18]: True In [19]: isinstance(it,collections.Iterable) Out[19]: True In [20]: isinstance(it,collections.Iterator) Out[20]: True
quelle
Nur für den Fall, dass Sie sich nicht sicher sind, was der Unterschied zwischen Iterables und Iteratoren ist. Ein Iterator ist ein Objekt, das einen Datenstrom darstellt. Es implementiert das Iteratorprotokoll:
__iter__
Methodenext
MethodeWiederholte Aufrufe der next () -Methode des Iterators geben aufeinanderfolgende Elemente im Stream zurück. Wenn keine Daten mehr verfügbar sind, ist das Iteratorobjekt erschöpft und alle weiteren Aufrufe der next () -Methode lösen StopIteration erneut aus.
Auf der anderen Seite implementieren iterierbare Objekte die
__iter__
Methode, die beim Aufruf einen Iterator zurückgibt, der mehrere Durchgänge über ihre Daten ermöglicht. Iterierbare Objekte können wiederverwendet werden. Sobald sie erschöpft sind, können sie erneut wiederholt werden. Sie können mit deriter
Funktion in Iteratoren konvertiert werden .Wenn Sie also eine Liste (iterierbar) haben, können Sie Folgendes tun:
>>> l = [1,2,3,4] >>> for i in l: ... print i, 1 2 3 4 >>> for i in l: ... print i, 1 2 3 4
Wenn Sie Ihre Liste in einen Iterator konvertieren:
>>> il = l.__iter__() # equivalent to iter(l) >>> for i in il: ... print i, 1 2 3 4 >>> for i in il: ... print i, >>>
quelle
List ist kein Iterator, aber list enthält ein Iteratorobjekt.
__iter__
Wenn Sie also versuchen, die for-Schleife in einer beliebigen Liste zu verwenden, ruft die__iter__
Methode loop auf und ruft das Iteratorobjekt ab. Anschließend wird die Methode next () der Liste verwendet.x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] it = x.__iter__()
it
Enthält jetzt ein Iterator-Objekt,x
das Sie verwenden können,it.next()
bis die StopIteration-Ausnahme ausgelöst wirdquelle
AttributeError: 'list' object has no attribute 'iter'
__iter__
Stapelüberlauf konvertiert ihn in Fettdruck, indem der in meiner Antwort erwähnte Unterstrich ersetzt wird. Ich war mir dieser Sache nicht bewusstit.next()
erhöhtAttributeError: 'list_iterator' object has no attribute 'next'
. Stattdessen gibt esnext(it)