Iteratoren

Python SELF DE
Level 19 , Lektion 4
Verfügbar

5.1 Iterable und Iterator

Wie du schon weißt, sind Iteratoren Objekte, die das Iterator-Protokoll implementieren und somit nacheinander Elemente aus einer Sammlung abrufen können. Iteratoren werden in Python häufig verwendet, um Elemente von Sequenzen wie Listen, Tupeln und Strings zu durchlaufen.

Schauen wir uns an, wie Iteratoren aufgebaut sind und wie man sie verwendet.

Iterierbares Objekt (Iterable)

Damit ein Objekt in einer for-Schleife durchlaufen werden kann, muss es iterierbar – Iterable – sein. Das bedeutet, dass unser Objekt die Methode __iter__() implementieren muss, die ein Iterator-Objekt zurückgibt.

Iterator-Objekt (Iterator)

Dies ist ein spezielles Objekt, das die Funktion __next__() hat, um das nächste Element der Sequenz zurückzugeben. Wenn keine Elemente mehr vorhanden sind, löst die Methode __next__() die Ausnahme StopIteration als Zeichen zum Stoppen der Iteration aus.

Der Iterator muss auch die Methode __iter__() implementieren, die den Iterator selbst zurückgibt.

Beispiel mit eingebauten Python-Funktionen

In diesem Beispiel ist die Liste numbers ein iterierbares Objekt. Wir erhalten den Iterator mit der Funktion iter() und nutzen die Funktion next(), um die Elemente so lange zu durchlaufen, bis die Ausnahme StopIteration ausgelöst wird.


# Iterierbares Objekt
numbers = [1, 2, 3, 4, 5]
            
# Erhalten des Iterators aus dem iterierbaren Objekt
iterator = iter(numbers)
            
# Verwendung des Iterators zum Durchlaufen der Elemente
try:
    while True:
        number = next(iterator)
        print(number)
except StopIteration:
    pass
        

Genau das passiert, wenn du Code dieser Art schreibst:


# Iterierbares Objekt
numbers = [1, 2, 3, 4, 5]
            
for number in numbers:
    print(number)
        

5.2 Das Wesen des Iterators

Ein Iterator ist ein Objekt, das uns hilft, eine Gruppe von Elementen nacheinander zu durchlaufen. Die Implementierungen können sehr unterschiedlich sein. Lass uns eine eigene Klasse schreiben, die alle Anforderungen umsetzt, die an einen Iterator gestellt werden.

Schritt 1. Zuerst erstellen wir unsere eigene Klasse

Lass ihn der Reihe nach Zahlen von start bis end zurückgeben


class MyIterator:
    def __init__(self, start, end):
        self.current = start
        self.end = end
        

Schritt 2. Unterstützung der Funktion __iter__

Jetzt müssen wir ihm die Funktion __iter__ hinzufügen, die das Iterator-Objekt zurückgibt, bei dem die Funktion __next()__ aufgerufen wird. Wir werden eine Referenz auf unser eigenes Objekt zurückgeben – das ist nicht verboten.


class MyIterator:
    def __init__(self, start, end):
        self.current = start
        self.end = end
        
    def __iter__(self):
        return self
        

Schritt 3. Unterstützung der Funktion __next__

Jetzt müssen wir unserem Objekt-Iterator die Funktion __next__ hinzufügen, die das nächste Element unserer Liste zurückgeben wird. Wir werden einfach die Variable current verwenden:


def __next__(self):
    current = self.current
    self.current += 1
    return current
        

Schritt 4. Stoppen des Iterators

Wenn der Iterator bereits alle geplanten Werte zurückgegeben hat, muss er die Ausnahme StopIteration auslösen. Lass uns unsere letzte Funktion ein wenig anpassen:


def __next__(self):
    if self.current >= self.end: raise StopIteration
    current = self.current
    self.current += 1
    return current
        

Super. Jetzt können wir unseren Iterator verwenden. Hier ist ein Beispiel für unseren gesamten Code:


class MyIterator:
    def __init__(self, start, end):
        self.current = start
        self.end = end
        
    def __iter__(self):
        return self
        
    def __next__(self):
        if self.current >= self.end:
            raise StopIteration
        current = self.current
        self.current += 1
        return current
        
# Erstellen einer Instanz des benutzerdefinierten Iterators
my_iter = MyIterator(1, 5)
        
# Verwendung des Iterators zum Durchlaufen der Elemente
for num in my_iter:
    print(num)

5.3 Der richtige Iterator

Warum ist der Iterator aus dem vorherigen Beispiel nicht ideal? Ja, er ist ein Iterator und funktioniert, aber er ist zu primitiv. Man kann nicht gleichzeitig mit mehreren Iteratoren durch dieselbe Sammlung von Elementen gehen.

Es wäre richtiger, Code zu schreiben, der im __iter__-Methode nicht eine Referenz auf sich selbst, sondern ein separates Objekt zurückgibt, das die Elemente korrekt ausgibt.

Beispiel:


class MyIterable:
    def __init__(self, data):
        self.data = data
    
    def __iter__(self):
        return MyIterator(self.data)
    
class MyIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.index >= len(self.data):
            raise StopIteration
        item = self.data[self.index]
        self.index += 1
        return item
    
# Nutzung
my_iterable = MyIterable([1, 2, 3, 4])
for item in my_iterable:
    print(item)
    

In diesem Beispiel haben wir zwei Klassen — in die erste wird die Sammlung übergeben, durch die wir mit dem Iterator gehen werden. Die zweite ist der Iterator, der die Elemente der Sammlung in der Methode next() zurückgibt. Er ist auch ziemlich einfach, aber genau so sollte man Iteratoren in seine Klassen einfügen.

1
Umfrage/Quiz
Module und Pakete, Level 19, Lektion 4
Nicht verfügbar
Module und Pakete
Module und Pakete
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION