Was genau sind Iterator, Iterierbarkeit und Iteration?


442

Was ist die grundlegendste Definition von "iterierbar", "iterator" und "iteration" in Python?

Ich habe mehrere Definitionen gelesen, kann aber die genaue Bedeutung nicht identifizieren, da sie immer noch nicht berücksichtigt wird.

Kann mir bitte jemand mit den 3 Definitionen in Laienbegriffen helfen?

Antworten:


530

Iteration ist ein allgemeiner Begriff, um jeden Gegenstand von etwas nacheinander zu nehmen. Jedes Mal, wenn Sie eine explizite oder implizite Schleife verwenden, um eine Gruppe von Elementen zu durchlaufen, dh Iteration.

In Python haben iterable und iterator bestimmte Bedeutungen.

Eine iterable ist ein Objekt mit einer __iter__Methode, die einen Iterator zurückgibt oder die eine __getitem__Methode definiert , die sequentielle Indizes ab Null annehmen kann (und eine auslöst, IndexErrorwenn die Indizes nicht mehr gültig sind). Ein Iterable ist also ein Objekt, von dem Sie einen Iterator erhalten können .

Ein Iterator ist ein Objekt mit einer next(Python 2) - oder __next__(Python 3) -Methode.

Immer wenn Sie in Python eine forSchleife mapoder ein Listenverständnis usw. verwenden, wird die nextMethode automatisch aufgerufen, um jedes Element vom Iterator abzurufen und so den Iterationsprozess zu durchlaufen .

Ein guter Ort, um mit dem Lernen zu beginnen, ist der Abschnitt mit den Iteratoren des Lernprogramms und der Abschnitt mit den Iteratortypen auf der Seite mit den Standardtypen . Nachdem Sie die Grundlagen verstanden haben, probieren Sie den Abschnitt Iteratoren des HOWTO zur funktionalen Programmierung aus .


1
Beachten Sie, dass collections.abc.AsyncIteratorTests für __aiter__und __anext__Methoden. Dies ist eine neue Ergänzung in 3.6.
Janus Troelsen

1
@jlh warum __len__sollte unbedingt mit Iteration verbunden sein? Wie würde es Ihnen helfen, die Länge von etwas zu kennen, um darüber nachzudenken?
Shadowtalker

2
@shadowtalker Es wäre hilfreich zu wissen, welche Indizes gültig sind, damit Sie wissen, mit welchen Indizes verwendet werden kann __getitem__.
jlh

4
@jlh es hört sich so an, als ob Sie ein sehr eigensinniges Verhalten vorschlagen. Bedenken Sie, dass dies {'a': 'hi', 'b': 'bye'}eine Länge von 2 hat, aber nicht durch 0, 1 oder 2 indiziert werden kann.
Shadowtalker

2
@ Schattentalker. Aber ein Diktat hat eine __iter__Methode. Ich denke, jlh bezieht sich auf Objekte, die spezifisch iterierbar sind, weil sie definieren: "Eine __getitem__Methode, die sequentielle Indizes ab Null annehmen kann".
Rich

337

Hier ist die Erklärung, die ich beim Unterrichten von Python-Klassen verwende:

Ein ITERABLE ist:

  • alles, was durchlaufen werden kann (dh Sie können eine Zeichenfolge oder Datei durchlaufen) oder
  • alles, was auf der rechten Seite einer for-Schleife erscheinen kann: for x in iterable: ...oder
  • Alles, was Sie damit anrufen können iter(), gibt einen ITERATOR zurück: iter(obj)oder
  • Ein Objekt, das definiert, __iter__dass ein neuer ITERATOR zurückgegeben wird, oder eine __getitem__Methode, die für die indizierte Suche geeignet ist.

Ein ITERATOR ist ein Objekt:

  • mit einem Zustand, der sich daran erinnert, wo er sich während der Iteration befindet,
  • mit einer __next__Methode, die:
    • Gibt den nächsten Wert in der Iteration zurück
    • Aktualisiert den Status so, dass er auf den nächsten Wert zeigt
    • signalisiert, wann es durch Anheben erfolgt StopIteration
  • und das ist selbstiterierbar (was bedeutet, dass es eine __iter__Methode gibt, die zurückgibt self).

Anmerkungen:

  • Die __next__Methode in Python 3 wird nextin Python 2 und geschrieben
  • Die integrierte Funktion next()ruft diese Methode für das an sie übergebene Objekt auf.

Zum Beispiel:

>>> s = 'cat'      # s is an ITERABLE
                   # s is a str object that is immutable
                   # s has no state
                   # s has a __getitem__() method 

>>> t = iter(s)    # t is an ITERATOR
                   # t has state (it starts by pointing at the "c"
                   # t has a next() method and an __iter__() method

>>> next(t)        # the next() function returns the next value and advances the state
'c'
>>> next(t)        # the next() function returns the next value and advances
'a'
>>> next(t)        # the next() function returns the next value and advances
't'
>>> next(t)        # next() raises StopIteration to signal that iteration is complete
Traceback (most recent call last):
...
StopIteration

>>> iter(t) is t   # the iterator is self-iterable

Was meinst du mit frischem Iterator?
lmiguelvargasf

13
@lmiguelvargasf "Frisch" wie in "neu und nicht konsumiert" im Gegensatz zu "erschöpft oder teilweise konsumiert". Die Idee ist, dass ein neuer Iterator am Anfang beginnt, während ein teilweise verwendeter Iterator dort weitermacht, wo er aufgehört hat.
Raymond Hettinger

Ihre 2., 3. und 4. Aufzählungszeichen geben deutlich an, was Sie in Bezug auf bestimmte Python-Konstrukte oder integrierte Funktionen oder Methodenaufrufe meinen. Aber die erste Kugel ("alles, was durchgeschleift werden kann") hat diese Klarheit nicht. Außerdem scheint die erste Kugel eine Überlappung mit der zweiten Kugel zu haben, da es sich bei der zweiten Kugel um forSchleifen handelt und bei der ersten Kugel um "Schleifen". Könnten Sie diese bitte ansprechen?
Brunnenkopf

2
Pls erwägen, "alles, mit dem Sie anrufen können iter()" als "alles, an das Sie weitergeben können iter()"
fountainhead

98

Die obigen Antworten sind großartig, aber wie das meiste, was ich gesehen habe, betonen Sie die Unterscheidung nicht genug für Leute wie mich.

Außerdem neigen Menschen dazu, "zu pythonisch" zu werden, indem sie zuvor Definitionen wie "X ist ein Objekt mit __foo__()Methode" setzen. Solche Definitionen sind korrekt - sie basieren auf der Philosophie der Ententypisierung, aber der Fokus auf Methoden liegt tendenziell dazwischen, wenn versucht wird, das Konzept in seiner Einfachheit zu verstehen.

Also füge ich meine Version hinzu.


In natürlicher Sprache

  • Bei der Iteration wird jeweils ein Element in einer Reihe von Elementen aufgenommen.

In Python

  • iterable ist ein Objekt, das iterable ist, was einfach ausgedrückt bedeutet, dass es in der Iteration verwendet werden kann, z for. B. mit einer Schleife. Wie? Mit dem Iterator . Ich werde unten erklären.

  • ... während der Iterator ein Objekt ist, das definiert, wie die Iteration tatsächlich durchgeführt wird - insbesondere, was das nächste Element ist. Deshalb muss es next()Methode haben.

Iteratoren sind selbst auch iterierbar, mit dem Unterschied, dass ihre __iter__()Methode dasselbe Objekt ( self) zurückgibt , unabhängig davon, ob ihre Elemente von früheren Aufrufen an verbraucht wurden oder nicht next().


Was denkt der Python-Interpreter, wenn er eine for x in obj:Aussage sieht ?

Schau, eine forSchleife. Sieht aus wie ein Job für einen Iterator ... Lassen Sie uns einen bekommen. ... Da ist dieser objTyp, also fragen wir ihn.

"Mr. obj, haben Sie Ihren Iterator?" (... ruft an iter(obj), was anruft obj.__iter__(), was glücklich einen glänzenden neuen Iterator verteilt _i.)

OK, das war einfach ... Dann fangen wir an zu iterieren. ( x = _i.next()... x = _i.next()...)

Da Mr. objdiesen Test erfolgreich abgeschlossen hat (indem eine bestimmte Methode einen gültigen Iterator zurückgibt), belohnen wir ihn mit einem Adjektiv: Sie können ihn jetzt "iterable Mr. obj" nennen.

In einfachen Fällen profitieren Sie jedoch normalerweise nicht davon, dass Iterator und Iterator separat verfügbar sind. Sie definieren also nur ein Objekt, das auch ein eigener Iterator ist. (Python ist es eigentlich egal, dass _idas, was von objausgegeben wurde, nicht so glänzend war, sondern nur das objselbst.)

Aus diesem Grund können Sie in den meisten Beispielen, die ich gesehen habe (und was mich immer wieder verwirrt hat), Folgendes sehen:

class IterableExample(object):

    def __iter__(self):
        return self

    def next(self):
        pass

anstatt

class Iterator(object):
    def next(self):
        pass

class Iterable(object):
    def __iter__(self):
        return Iterator()

Es gibt jedoch Fälle, in denen Sie davon profitieren können, dass der Iterator vom iterablen getrennt wird, z. B. wenn Sie eine Reihe von Elementen, aber mehr "Cursor" haben möchten. Wenn Sie beispielsweise mit "aktuellen" und "bevorstehenden" Elementen arbeiten möchten, können Sie für beide separate Iteratoren verwenden. Oder mehrere Threads, die aus einer riesigen Liste gezogen werden: Jeder kann seinen eigenen Iterator haben, um alle Elemente zu durchlaufen. Siehe die Antworten von @ Raymond und @ glglgl oben.

Stellen Sie sich vor, was Sie tun könnten:

class SmartIterableExample(object):

    def create_iterator(self):
        # An amazingly powerful yet simple way to create arbitrary
        # iterator, utilizing object state (or not, if you are fan
        # of functional), magic and nuclear waste--no kittens hurt.
        pass    # don't forget to add the next() method

    def __iter__(self):
        return self.create_iterator()

Anmerkungen:

  • Ich wiederhole noch einmal: Iterator ist nicht iterierbar . Der Iterator kann nicht als "Quelle" in einer forSchleife verwendet werden. Was die forSchleife hauptsächlich benötigt, ist __iter__() (das gibt etwas mit zurück next()).

  • Natürlich forist dies nicht die einzige Iterationsschleife, daher gilt das oben Gesagte auch für einige andere Konstrukte ( while...).

  • Iteratoren next()können StopIteration auslösen, um die Iteration zu stoppen. Muss aber nicht, es kann für immer iterieren oder andere Mittel verwenden.

  • Im obigen "Denkprozess" _iexistiert nicht wirklich. Ich habe diesen Namen erfunden.

  • Es gibt eine kleine Änderung in Python 3.x: Die next()Methode (nicht die eingebaute) muss jetzt aufgerufen werden __next__(). Ja, das hätte die ganze Zeit so sein sollen.

  • Sie können sich das auch so vorstellen: iterable hat die Daten, iterator zieht das nächste Element

Haftungsausschluss: Ich bin kein Entwickler eines Python-Interpreters, daher weiß ich nicht genau, was der Interpreter "denkt". Die obigen Überlegungen zeigen lediglich, wie ich das Thema anhand anderer Erklärungen, Experimente und realer Erfahrungen eines Python-Neulings verstehe.


1
Das ist großartig - aber ich bin immer noch ein bisschen verwirrt. Ich dachte, Ihre gelbe Box sagt, dass eine forSchleife einen Iterator benötigt ("Schauen Sie, eine for-Schleife. Sieht aus wie ein Job für einen Iterator ... Lassen Sie uns einen bekommen."). Aber dann sagen Sie in den Anmerkungen am Ende, dass "Iterator nicht als Quelle in einer forSchleife verwendet werden kann" ...?
Racing Tadpole

Warum geben Sie nur passden Code für diese nextDefinitionen ein? Ich gehe davon aus, dass Sie nur meinen, dass jemand einen Weg implementieren muss, um den nächsten zu erhalten, da der nächste etwas zurückgeben muss.
Nealmcb

@nealmcb Ja, ich denke, das war es, was Vergangenheit für mich bedeutete. ( pass
Dafür

@AloisMahdal Ahh, ich hatte diese Verwendung noch nie gesehen. Wenn ich sehe pass, denke ich, dass es aus syntaktischen Gründen da ist. Ich bin gerade auf die Antworten am Auslassungsobjekt gestoßen, die sehr interessant sind: Sie können ...einen Block "später erledigen" angeben. NotImplementedist ebenfalls verfügbar.
Nealmcb

Ich finde es gut, dass Sie die Unterscheidung zwischen einem Iterator und einem Iterator betonen, aber diese Antwort widerspricht sich. Zuerst schreiben Sie: "Iteratoren sind selbst auch iterierbar" (was mit dem übereinstimmt, was in der Python-Dokumentation geschrieben steht ). Aber später schreiben Sie: ' Iterator ist nicht iterierbar . Iterator kann nicht als "Quelle" in forSchleife verwendet werden. Ich verstehe den Punkt Ihrer Antwort und mag es anders, aber ich denke, es würde davon profitieren, dies zu beheben.
Rich

22

Ein iterable ist ein Objekt, das eine __iter__()Methode hat. Es kann möglicherweise mehrmals wiederholt werden, z. B. list()s und tuple()s.

Ein Iterator ist das Objekt, das iteriert. Es wird von einer __iter__()Methode zurückgegeben, gibt sich über eine eigene __iter__()Methode zurück und verfügt über eine next()Methode ( __next__()in 3.x).

Iteration ist der Prozess, bei dem dies next()bzw. __next__()bis es steigt StopIteration.

Beispiel:

>>> a = [1, 2, 3] # iterable
>>> b1 = iter(a) # iterator 1
>>> b2 = iter(a) # iterator 2, independent of b1
>>> next(b1)
1
>>> next(b1)
2
>>> next(b2) # start over, as it is the first call to b2
1
>>> next(b1)
3
>>> next(b1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> b1 = iter(a) # new one, start over
>>> next(b1)
1

Also ist es wirklich nur ein Objekt, das durch Container geht? Wäre das nützlich?
Thechrishaddad

Oft, aber nicht immer. Ein Generator-, Datei- oder Datenbankcursor kann nur einmal iteriert werden und ist daher ein eigener Iterator.
glglgl

Ich denke, b2 muss nicht unabhängig von b1 sein? Für diesen speziellen Fall ist es unabhängig, sicher kann ich es nicht unabhängig machen, sondern auch gültig Iterable.
Bin

@ Bin Ja. Wie und Iteratorist immer Iterableund ist sein eigenes Iterator, zwei Anrufe von iter()geben nicht notwendigerweise zwei unabhängige Iterators.
glglgl

13

Hier ist mein Spickzettel:

 sequence
  +
  |
  v
   def __getitem__(self, index: int):
  +    ...
  |    raise IndexError
  |
  |
  |              def __iter__(self):
  |             +     ...
  |             |     return <iterator>
  |             |
  |             |
  +--> or <-----+        def __next__(self):
       +        |       +    ...
       |        |       |    raise StopIteration
       v        |       |
    iterable    |       |
           +    |       |
           |    |       v
           |    +----> and +-------> iterator
           |                               ^
           v                               |
   iter(<iterable>) +----------------------+
                                           |
   def generator():                        |
  +    yield 1                             |
  |                 generator_expression +-+
  |                                        |
  +-> generator() +-> generator_iterator +-+

Quiz: Sehen Sie wie ...

  1. Jeder Iterator ist iterierbar?
  2. Die __iter__()Methode eines Containerobjekts kann als Generator implementiert werden.
  3. Ein Iterable mit einer __next__Methode ist nicht unbedingt ein Iterator?

Antworten:

  1. Jeder Iterator muss eine __iter__Methode haben. Haben __iter__ist genug, um iterierbar zu sein. Daher ist jeder Iterator iterierbar.
  2. Wenn __iter__es aufgerufen wird, sollte es einen Iterator zurückgeben ( return <iterator>im obigen Diagramm). Das Aufrufen eines Generators gibt einen Generatoriterator zurück, der eine Art Iterator ist.

    class Iterable1:
        def __iter__(self):
            # a method (which is a function defined inside a class body)
            # calling iter() converts iterable (tuple) to iterator
            return iter((1,2,3))
    
    class Iterable2:
        def __iter__(self):
            # a generator
            for i in (1, 2, 3):
                yield i
    
    class Iterable3:
        def __iter__(self):
            # with PEP 380 syntax
            yield from (1, 2, 3)
    
    # passes
    assert list(Iterable1()) == list(Iterable2()) == list(Iterable3()) == [1, 2, 3]
  3. Hier ist ein Beispiel:

    class MyIterable:
    
        def __init__(self):
            self.n = 0
    
        def __getitem__(self, index: int):
            return (1, 2, 3)[index]
    
        def __next__(self):
            n = self.n = self.n + 1
            if n > 3:
                raise StopIteration
            return n
    
    # if you can iter it without raising a TypeError, then it's an iterable.
    iter(MyIterable())
    
    # but obviously `MyIterable()` is not an iterator since it does not have
    # an `__iter__` method.
    from collections.abc import Iterator
    assert isinstance(MyIterable(), Iterator)  # AssertionError

1
Im Quiz habe ich nur den ersten Punkt verstanden. dh der Iterator wird zu einer iterierbaren __iter__Methode. Können Sie bitte den 2. und 3. Punkt
näher erläutern,

@AnV: Soweit ich weiß: re 2.: Gibt __iter__()einen Iterator zurück. Ein Generator ist ein Iterator, daher kann er für diesen Zweck verwendet werden. Zu 3.: Ich kann hier nur raten, aber ich denke, wenn __iter__()es fehlt oder nicht zurückkehrt self, ist es kein Iterator, weil ein Iterator __iter__()zurückkehren muss self.
glglgl

10

Ich weiß nicht, ob es jemandem hilft, aber ich mag es immer, Konzepte in meinem Kopf zu visualisieren, um sie besser zu verstehen. Da ich einen kleinen Sohn habe, visualisiere ich das iterable / iterator-Konzept mit Bausteinen und Whitepaper.

Angenommen, wir sind im dunklen Raum und auf dem Boden haben wir Ziegel für meinen Sohn. Steine ​​unterschiedlicher Größe und Farbe spielen jetzt keine Rolle mehr. Angenommen, wir haben 5 solche Steine. Diese 5 Steine ​​können als Objekt beschrieben werden - sagen wir mal Steinbausatz . Wir können mit diesem Baustein-Kit viele Dinge tun - können einen nehmen und dann den zweiten und dann den dritten nehmen, die Ziegelplätze wechseln, den ersten Ziegel über den zweiten legen. Damit können wir viele Dinge tun. Daher ist dieses Baustein-Kit ein iterierbares Objekt oder eine iterierbare Sequenz, da wir jeden Baustein durchgehen und etwas damit tun können. Wir können es wie mein kleiner Sohn nur tun - wir können mit spielen ein Ziegel auf einmal . Also wieder stelle ich mir dieses Bricks-Kit als ein voriterierbar .

Denken Sie jetzt daran, dass wir im dunklen Raum sind. Oder fast dunkel. Die Sache ist, dass wir diese Steine ​​nicht klar sehen, welche Farbe sie haben, welche Form usw. Selbst wenn wir etwas mit ihnen machen wollen - auch bekannt als Iteration durch sie -, wissen wir nicht wirklich was und wie, weil es so ist zu dunkel.

Was wir tun können, ist in der Nähe des ersten Ziegels - als Element eines Ziegelbausatzes - wir können ein Stück weißes fluoreszierendes Papier einlegen, damit wir sehen können, wo sich das erste Ziegelelement befindet. Und jedes Mal, wenn wir einen Ziegelstein aus einem Bausatz nehmen, ersetzen wir das weiße Stück Papier durch einen nächsten Ziegelstein, um dies im dunklen Raum sehen zu können. Dieses weiße Stück Papier ist nichts weiter als ein Iterator . Es ist auch ein Objekt . Aber ein Objekt mit dem, was wir mit Elementen unseres iterierbaren Objekts arbeiten und spielen können - Bricks Kit.

Das erklärt übrigens meinen frühen Fehler, als ich Folgendes in einem IDLE versuchte und einen TypeError bekam:

 >>> X = [1,2,3,4,5]
 >>> next(X)
 Traceback (most recent call last):
    File "<pyshell#19>", line 1, in <module>
      next(X)
 TypeError: 'list' object is not an iterator

Liste X hier war unser Ziegelset, aber KEIN weißes Stück Papier. Ich musste zuerst einen Iterator finden:

>>> X = [1,2,3,4,5]
>>> bricks_kit = [1,2,3,4,5]
>>> white_piece_of_paper = iter(bricks_kit)
>>> next(white_piece_of_paper)
1
>>> next(white_piece_of_paper)
2
>>>

Ich weiß nicht, ob es hilft, aber es hat mir geholfen. Wenn jemand die Visualisierung des Konzepts bestätigen / korrigieren könnte, wäre ich dankbar. Es würde mir helfen, mehr zu lernen.


6

Iterierbar : - etwas, das iterierbar ist, ist iterierbar; wie Sequenzen wie Listen, Strings usw. Auch hat es entweder die __getitem__Methode oder eine __iter__Methode. Wenn wir nun die iter()Funktion für dieses Objekt verwenden, erhalten wir einen Iterator.

Iterator : - Wenn wir das Iteratorobjekt von der iter()Funktion erhalten; Wir rufen die __next__()Methode (in Python3) oder einfach next()(in Python2) auf, um die Elemente einzeln abzurufen. Diese Klasse oder Instanz dieser Klasse wird als Iterator bezeichnet.

Aus Dokumenten: -

Die Verwendung von Iteratoren durchdringt und vereinheitlicht Python. Hinter den Kulissen ruft die for-Anweisung  iter() das Containerobjekt auf. Die Funktion gibt ein Iteratorobjekt zurück, das die Methode definiert,  __next__() die einzeln auf Elemente im Container zugreift. Wenn keine weiteren Elemente vorhanden sind, wird  __next__() eine StopIteration-Ausnahme ausgelöst, die die for-Schleife zum Beenden anweist. Sie können die __next__() Methode mit der  next() integrierten Funktion aufrufen  . Dieses Beispiel zeigt, wie alles funktioniert:

>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    next(it)
StopIteration

Ex einer Klasse: -

class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)
    def __iter__(self):
        return self
    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]


>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for char in rev:
...     print(char)
...
m
a
p
s

4

Ich denke nicht, dass Sie es viel einfacher als die Dokumentation bekommen können , aber ich werde versuchen:

  • Iterable kann wiederholt werden. In der Praxis bedeutet dies normalerweise eine Sequenz, z. B. etwas, das einen Anfang und ein Ende hat, und eine Möglichkeit, alle darin enthaltenen Elemente durchzugehen.
  • Sie können sich Iterator als eine Hilfspseudomethode (oder ein Pseudoattribut) vorstellen, die das nächste (oder erste) Element in der Iterable angibt (oder enthält) . (In der Praxis ist es nur ein Objekt, das die Methode definiert. next())

  • Die Iteration lässt sich wahrscheinlich am besten durch die Merriam-Webster- Definition des Wortes erklären :

b: die Wiederholung einer Folge von Computeranweisungen eine bestimmte Anzahl von Malen oder bis eine Bedingung erfüllt ist - vergleichen Sie die Rekursion


3
iterable = [1, 2] 

iterator = iter(iterable)

print(iterator.__next__())   

print(iterator.__next__())   

damit,

  1. iterableist ein Objekt , das durchlaufen werden kann . zB Liste, String, Tupel etc.

  2. Wenn Sie die iterFunktion für unser iterableObjekt verwenden, wird ein Iteratorobjekt zurückgegeben.

  3. Jetzt hat dieses Iteratorobjekt eine Methode namens __next__(in Python 3 oder nur nextin Python 2), mit der Sie auf jedes Element von iterable zugreifen können.

Die Ausgabe des oben genannten Codes lautet also:

1

2


3

Iterables haben eine __iter__Methode, die jedes Mal einen neuen Iterator instanziiert.

Iteratoren implementieren eine __next__Methode, die einzelne Elemente zurückgibt, und eine __iter__Methode, die zurückgibt self.

Daher sind Iteratoren auch iterierbar, aber iterable sind keine Iteratoren.

Luciano Ramalho, fließender Python.


2

Vor dem Umgang mit den Iterablen und dem Iterator ist die Sequenz der Hauptfaktor, der über die Iterablen und den Iterator entscheidet

Sequenz: Sequenz ist die Sammlung von Daten

Iterable: Iterable sind die Objekte vom Sequenztyp, die die __iter__Methode unterstützen.

Iter-Methode: Die Iter-Methode nimmt die Sequenz als Eingabe und erstellt ein Objekt, das als Iterator bezeichnet wird

Iterator: Iterator sind die Objekte, die die nächste Methode aufrufen und die Sequenz durchlaufen. Beim Aufrufen der nächsten Methode wird das aktuell durchlaufene Objekt zurückgegeben.

Beispiel:

x=[1,2,3,4]

x ist eine Sequenz, die aus der Sammlung von Daten besteht

y=iter(x)

Beim Aufrufen iter(x)wird nur dann ein Iterator zurückgegeben, wenn das x-Objekt über eine iter-Methode verfügt. Andernfalls wird eine Ausnahme ausgelöst. Wenn es einen Iterator zurückgibt, wird y wie folgt zugewiesen:

y=[1,2,3,4]

Da y ein Iterator ist, unterstützt es die next()Methode

Beim Aufruf der nächsten Methode werden die einzelnen Elemente der Liste nacheinander zurückgegeben.

Wenn wir nach der Rückgabe des letzten Elements der Sequenz die nächste Methode erneut aufrufen, wird ein StopIteration-Fehler ausgelöst

Beispiel:

>>> y.next()
1
>>> y.next()
2
>>> y.next()
3
>>> y.next()
4
>>> y.next()
StopIteration

Nur eine Beobachtung: y = iter (x) ist nicht genau y = [1,2,3,4], da y jetzt ein Iteratorobjekt ist. Vielleicht sollten Sie einen Kommentar hinzufügen, um zu verdeutlichen, dass es sich nicht um eine Liste, sondern um ein Iteratorobjekt handelt, oder die Darstellung ändern.
Coelhudo

-6

In Python ist alles ein Objekt. Wenn ein Objekt als iterierbar bezeichnet wird, bedeutet dies, dass Sie das Objekt als Sammlung durchlaufen (dh iterieren) können.

Arrays zum Beispiel sind iterierbar. Sie können sie mit einer for-Schleife durchlaufen und von Index 0 zu Index n wechseln, wobei n die Länge des Array-Objekts minus 1 ist.

Wörterbücher (Schlüssel / Wert-Paare, auch assoziative Arrays genannt) können ebenfalls iteriert werden. Sie können durch ihre Schlüssel treten.

Offensichtlich sind die Objekte, die keine Sammlungen sind, nicht iterierbar. Ein Bool-Objekt hat beispielsweise nur einen Wert, True oder False. Es ist nicht iterierbar (es würde keinen Sinn machen, dass es ein iterierbares Objekt ist).

Weiterlesen. http://www.lepus.org.uk/ref/companion/Iterator.xml


6
Objekte, die keine Sammlungen sind, können nicht iteriert werden. Dies ist im Allgemeinen nicht der Fall. Um nur einige Beispiele zu nennen: Generatoren sind iterierbar, aber keine Sammlungen, und die Iteratorobjekte, die durch Aufrufen iter()der Standardauflistungstypen erstellt wurden, sind iterierbar, aber selbst keine Sammlungen.
Mark Amery
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.