it-swarm.com.de

Was genau sind Iterator, Iterierbar und Iteration?

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

Ich habe mehrere Definitionen gelesen, kann die genaue Bedeutung jedoch nicht identifizieren, da sie immer noch nicht erfasst wird.

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

395
thechrishaddad

Iteration ist ein allgemeiner Begriff für das Aufnehmen der einzelnen Elemente nacheinander. Jedes Mal, wenn Sie eine explizite oder implizite Schleife verwenden, um eine Gruppe von Elementen zu durchlaufen, wird dies als Iteration bezeichnet.

In Python haben iterable und iterator bestimmte Bedeutungen.

Ein iterable ist ein Objekt mit einer Methode __iter__, die ein iterator zurückgibt oder eine Methode __getitem__ definiert, die sequentielle Indizes annehmen kann beginnend mit Null (und löst ein IndexError aus, wenn die Indizes nicht mehr gültig sind). Ein iterable ist also ein Objekt, von dem Sie ein iterator erhalten können.

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

Immer wenn Sie eine for -Schleife oder map oder ein Listenverständnis usw. in Python verwenden, wird die next -Methode automatisch aufgerufen, um jedes Element aus ) abzurufen Iterator , wodurch der Prozess von Iteration durchlaufen wird.

Ein guter Einstiegspunkt wäre der Abschnitt Iteratoren im Tutorial und der Abschnitt Iteratortypen auf der Seite mit den Standardtypen . Wenn Sie die Grundlagen verstanden haben, probieren Sie den Abschnitt Iteratoren im HOWTO zur funktionalen Programmierung .

470
agf

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

Eine ITERABLE ist:

  • alles, was durchlaufen werden kann (d. h. 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 mit iter() aufrufen können, gibt einen ITERATOR zurück: iter(obj) oder
  • ein Objekt, das __iter__ definiert, das einen neuen ITERATOR zurückgibt, oder eine __getitem__ -Methode, die für die indizierte Suche geeignet ist.

Ein ITERATOR ist ein Objekt:

  • mit Zustand, der sich erinnert, wo es während der Iteration ist,
  • mit einer __next__ -Methode, die:
    • gibt den nächsten Wert in der Iteration zurück
    • aktualisiert den Status, um auf den nächsten Wert zu zeigen
    • signalisiert, wann es getan wird, indem StopIteration angehoben wird
  • und das ist selbst iterierbar (was bedeutet, dass es eine __iter__ -Methode gibt, die self zurückgibt).

Anmerkungen:

  • Die __next__ -Methode in Python 3 ist next in Python 2 und
  • Die eingebaute Funktion next() ruft diese Methode für das ü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
302

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 die Leute dazu, "zu pythonisch" zu werden, indem sie Definitionen wie "X ist ein Objekt, das die Methode __foo__()" vor sich hat. Solche Definitionen sind korrekt - sie basieren auf der Duck-Typing-Philosophie, 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

  • Iteration ist der Vorgang, bei dem jeweils ein Element in einer Reihe von Elementen genommen wird.

In Python

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

  • ... while Iterator ist ein Objekt, das definiert , wie die Iteration tatsächlich durchgeführt wird - spezifisch Was ist das nächste Element? Aus diesem Grund muss es die Methode next() haben.

Iteratoren können auch selbst iteriert werden, mit dem Unterschied, dass ihre Methode __iter__() dasselbe Objekt (self) zurückgibt, unabhängig davon, ob ihre Elemente durch vorherige Aufrufe von next() verbraucht wurden oder nicht.


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

Schauen Sie, eine for Schleife. Sieht nach einem Job für einen Iterator aus ... Lassen Sie uns einen besorgen. ... Da ist dieser obj Typ, also lass ihn uns fragen.

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

OK, das war einfach ... Dann lass uns anfangen zu iterieren. (x = _i.next() ... x = _i.next()...)

Da Herr obj diesen Test erfolgreich absolviert 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 Iterable separat ausgeführt werden. Sie definieren also nur ein Objekt, das auch ein eigener Iterator ist. (Python ist es eigentlich egal, dass _i von obj nicht so glänzend war, sondern nur das obj selbst.)

Dies ist der Grund, warum in den meisten Beispielen, die ich gesehen habe (und was mich immer wieder verwirrt hat), Folgendes zu sehen ist:

class IterableExample(object):

    def __iter__(self):
        return self

    def next(self):
        pass

anstatt von

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 iterierbaren getrennt wird, z. B. wenn Sie eine Zeile mit Elementen, aber mehr "Cursor" möchten. Wenn Sie beispielsweise mit "aktuellen" und "kommenden" Elementen arbeiten möchten, können Sie für beide separate Iteratoren verwenden. Oder mehrere Threads aus einer riesigen Liste: Jeder kann einen eigenen Iterator haben, um alle Elemente zu durchlaufen. Siehe @ Raymond's und @ glglgl's Antworten 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 . Iterator kann nicht als "Quelle" in der for -Schleife verwendet werden. Was die for -Schleife in erster Linie benötigt, ist __iter__() (die etwas mit next() zurückgibt).

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

  • Die next() des Iterators kann StopIteration auslösen, um die Iteration zu stoppen. Muss jedoch nicht, es kann für immer iterieren oder andere Mittel verwenden.

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

  • Es gibt eine kleine Änderung in Python 3.x: next() Methode (nicht die eingebaute) muss jetzt __next__() heißen. 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 sind nur eine Demonstration, wie ich das Thema aus anderen Erklärungen, Experimenten und praktischen Erfahrungen eines Python -Neus verstehe.

94
Alois Mahdal

Ein Iterable ist ein Objekt mit der Methode __iter__(). Es kann möglicherweise mehrmals durchlaufen 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 selbst über eine eigene __iter__() -Methode zurück und hat eine next() -Methode (__next__() in 3.x).

Iteration ist der Vorgang des Aufrufs von next() resp. __next__(), bis StopIteration ausgelöst wird.

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
21
glglgl

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

Angenommen, wir sind in der Dunkelkammer 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 Steine ​​wie diese. Diese 5 Bausteine ​​können als Objekt - sagen wir Bausteinbausatz beschrieben werden. Wir können viele Dinge mit diesem Ziegelbausatz machen - können einen nehmen und dann den zweiten und dann den dritten nehmen, können die Ziegelstellen wechseln, den ersten Ziegel über den zweiten setzen. Mit denen können wir viele Dinge machen. Daher ist dieses Bausteinset ein iterierbares Objekt oder Sequenz, da wir durch jeden Baustein gehen und etwas damit machen können. Wir können es nur so machen wie mein kleiner Sohn - wir können mit einem Ziegel zu einer Zeit spielen. Also wieder stelle ich mir dieses Bricks Kit als iterabel vor.

Denken Sie jetzt daran, dass wir uns im dunklen Raum befinden. Oder fast dunkel. Die Sache ist, dass wir diese Steine ​​nicht klar sehen, welche Farbe sie haben, welche Form usw. Also, auch wenn wir etwas mit ihnen machen wollen - auch bekannt als durch sie iterieren - tun wir das nicht wirklich weiß was und wie denn es ist zu dunkel.

Was wir tun können, ist in der Nähe des ersten Ziegels - als Element eines Ziegelbausatzes - können wir ein Stück weißes fluoreszierendes Papier legen, 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 das 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 iterablen Objekt-Bausatzes spielen und arbeiten können.

Das erklärt übrigens meinen frühen Fehler, als ich Folgendes in einem IDLE ausprobierte 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 Ziegelbausatz, 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.

9
Nikolay Dudaev

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 ...

  • jeder iterator ist ein iterable?
  • die __iter__() -Methode eines Containerobjekts kann als Generator implementiert werden?
  • eine iterable plus eine __next__ -Methode ist nicht unbedingt ein Iterator?
7
AXO

Iterable: - etwas, das iterable ist, ist iterable; Ähnliche Sequenzen wie Listen, Strings usw. Außerdem hat es entweder die __getitem__ -Methode oder eine __iter__ -Methode. Wenn wir nun die Funktion iter() für dieses Objekt verwenden, erhalten wir einen Iterator.

Iterator: - Wenn wir das Iterator-Objekt von der Funktion iter() erhalten; Wir rufen die Methode __next__() (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() für das Containerobjekt auf. Die Funktion gibt ein Iterator-Objekt zurück, das die Methode __next__() definiert, die nacheinander auf Elemente im Container zugreift. Wenn keine weiteren Elemente vorhanden sind, löst __next__() eine StopIteration-Ausnahme aus, die die for-Schleife zum Beenden auffordert. Sie können die Methode __next__() mit der integrierten Funktion next() 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
Vicrobot

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

  • Iterierbar ist etwas, über das iteriert werden kann . In der Praxis bedeutet normalerweise eine Sequenz , z. Etwas, das einen Anfang und ein Ende hat und eine Möglichkeit bietet, alle darin enthaltenen Elemente durchzugehen.
  • Sie können sich Iterator als eine Hilfs-Pseudomethode (oder ein Pseudoattribut) vorstellen, die das nächste (oder erste) Element im iterabel . (In der Praxis ist es nur ein Objekt, das die Methode next() definiert.)

  • Iteration wird wahrscheinlich am besten durch das Merriam-Webster erklärt Definition des Wortes :

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

3
Kimvais
iterable = [1, 2] 

iterator = iter(iterable)

print(iterator.__next__())   

print(iterator.__next__())   

damit,

  1. iterable ist ein Objekt, das durchgeschleift sein kann. z.B. Liste, Zeichenfolge, Tupel usw.

  2. wenn Sie die iter -Funktion für unser iterable -Objekt verwenden, wird ein Iterator-Objekt zurückgegeben

  3. jetzt hat dieses Iterator-Objekt eine Methode namens __next__ (in Python 3 oder nur next in Python 2), mit der Sie can greife auf jedes Element von iterable zu.

die Ausgabe des obigen Codes wird also sein:

1

2

3
arpan kumar

Iterables haben eine __iter__ -Methode, die jedes Mal einen neuen Iterator instanziiert.

Iteratoren Implementieren Sie eine __next__ -Methode, die einzelne Elemente zurückgibt, und eine __iter__ -Methode, die self zurückgibt.

Daher sind Iteratoren auch iterabel, aber Iterablen sind keine Iteratoren.

Luciano Ramalho, fließender Python.

1
techkuz

Vor dem Umgang mit den Iterablen und dem Iterator ist der Hauptfaktor, der das Iterable und den Iterator bestimmt, die Sequenz

Sequenz: Sequenz ist die Sammlung von Daten

Iterable: Iterable sind die Sequenztypobjekte, die die Iter-Methode unterstützen.

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

Iterator: Iterator ist das Objekt, das die nächste Methode aufruft und die Sequenz durchläuft. Beim Aufrufen der nächsten Methode wird das Objekt zurückgegeben, das gerade durchlaufen wurde.

beispiel:

x=[1,2,3,4]

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

y=iter(x)

Beim Aufruf von iter (x) wird nur dann ein Iterator zurückgegeben, wenn das x-Objekt die iter-Methode hat, andernfalls wird eine Ausnahme ausgelöst. Wenn es einen Iterator zurückgibt, wird y folgendermaßen 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 das letzte Element der Sequenz zurückgeben und 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
1
Shadow