Iteratoren und Iterablen

Difference between Iterators and Iterables

Die Python-Foren und andere Frage-und-Antwort-Websites wie Quora und Stackoverflow sind voller Fragen zu "Iteratoren" und "iterierbar". Einige möchten wissen, wie sie definiert sind, andere möchten wissen, ob es eine einfache Möglichkeit gibt, zu überprüfen, ob ein Objekt ein Iterator oder ein Iterator ist. Zu diesem Zweck stellen wir eine Funktion zur Verfügung.

Wir haben gesehen, dass wir verschiedene Python-Objekte wie Listen, Tupel und Strings durchlaufen oder durchlaufen können. Zum Beispiel:

for stadt in ["Berlin", "Wien", "Zürich"]:
    print(stadt)
for sprache in ("Python", "Perl", "Ruby"):
    print(sprache)
for charakter in "Iteration ist einfach":
    print(charakter)
Berlin
Wien
Zürich
Python
Perl
Ruby
I
t
e
r
a
t
i
o
n
 
i
s
t
 
e
i
n
f
a
c
h

Diese Form der Schleife kann als Iteration angesehen werden. Die Iteration ist nicht auf explizite for-Schleifen beschränkt. Wenn Sie die Funktionssumme aufrufen, - z.b Auf einer Liste von ganzzahligen Werten - führen Sie auch eine Iteration durch.

Was ist der Unterschied zwischen einem iterierbaren und einem Iterator?

Einerseits sind sie gleich: Sie können mit einer for-Schleife über Iteratoren und Iterablen iterieren. Jeder Iterator ist auch ein Iterator, aber nicht jeder Iterator ist ein Iterator. Z.B. Eine Liste ist iterierbar, aber eine Liste ist kein Iterator! Ein Iterator kann mit der Funktion 'iter' aus einem Iterator erstellt werden. Um dies zu ermöglichen, benötigt die Klasse eines Objekts entweder eine Methode __iter__, die einen Iterator zurückgibt, oder eine Methode __getitem__ 'mit sequentiellen Indizes, die mit 0 beginnen.

Iteratoren sind Objekte mit der Methode __next__, die beim Aufruf der Funktion 'next ()' verwendet wird.

Was passiert also hinter den Kulissen, wenn eine for-Schleife ausgeführt wird? Die for-Anweisung ruft iter () für das Objekt auf (das ein sogenanntes Containerobjekt sein sollte), über das es eine Schleife ausführen soll. Wenn dieser Aufruf erfolgreich ist, gibt der Iterationsaufruf ein Iteratorobjekt zurück, das die Methode __next __ () definiert, die nacheinander auf Elemente des Objekts zugreift. Die Methode __next __ () löst eine StopIteration-Ausnahme aus, wenn keine weiteren Elemente verfügbar sind. Die for-Schleife wird beendet, sobald eine StopIteration-Ausnahme abgefangen wird. Sie können die Methode __next __ () mit der integrierten Funktion next () aufrufen. So funktioniert es:

städte = ["Berlin", "Wien", "Zürich"]
iterator_obj = iter(städte)
print(iterator_obj)
print(next(iterator_obj))
print(next(iterator_obj))
print(next(iterator_obj))
<list_iterator object at 0x000001B3A42F4F88>
Berlin
Wien
Zürich

Wenn wir noch einmal 'next (iterator_obj)' aufrufen würden, würde 'StopIteration' zurückgegeben.

Die folgende Funktion 'iterable' gibt True zurück, wenn das Objekt 'obj' iterierbar ist, andernfalls False.

def iterable(obj):
     try:
         iter(obj)
         return True
     except TypeError:
         return False 
        
for element in [34, [4, 5], (4, 5), {"a":4}, "dfsdf", 4.5]:
    print(element, "iterable: ", iterable(element))
34 iterable:  False
[4, 5] iterable:  True
(4, 5) iterable:  True
{'a': 4} iterable:  True
dfsdf iterable:  True
4.5 iterable:  False

Wir haben beschrieben, wie ein Iterator funktioniert. Wenn Sie Ihrer Klasse also ein Iteratorverhalten hinzufügen möchten, müssen Sie Ihrer Klasse die Methoden __iter__ und __next__ hinzufügen. Die Methode __iter__ gibt ein Iteratorobjekt zurück. Wenn die Klasse ein __next__ enthält, reicht es aus, dass die __iter__ Methode self zurückgibt, d. H. Einen Verweis auf sich selbst:

class Reverse:
    """
    Erstellt Iteratoren zum Rückwärtslaufen einer Sequenz.
    """
    
    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]
lst = [34, 978, 42]
lst_rückwärts = Reverse(lst)
for el in lst_rückwärts:
    print(el)
42
978
34