Warum können Iteratoren nicht mehrmals iteriert werden? Eine umfassende Untersuchung und Lösung
Betrachten Sie den folgenden Code:
def test(data): for row in data: print("first loop") for row in data: print("second loop")
Wenn Daten ein Iterator sind, z. B. ein Listeniterator oder ein Generatorausdruck, führt eine zweimalige Iteration darüber zu unerwarteten Ergebnissen :
>>> test(iter([1, 2])) first loop first loop >>> test((_ for _ in [1, 2])) first loop first loop
Diese Beispiele drucken „erste Schleife“ mehrmals, aber die „zweite Schleife“ wird nie gedruckt. Dieses Verhalten wirft die Frage auf: Warum funktioniert die Iteration beim ersten Mal, beim zweiten jedoch nicht? Und wie können wir dieser Einschränkung begegnen?
Iteratoren und Verbrauch verstehen
Ein Iterator ist ein Objekt, das jeweils einen Wert liefert. Bei der Iteration werden Iteratoren verbraucht, was bedeutet, dass sie nach dem Durchlaufen nicht noch einmal iteriert werden können. Das Gleiche gilt für Generatoren, Dateiobjekte und viele andere iterierbare Objekte.
Dieses Verbrauchsverhalten wird im folgenden Codeausschnitt veranschaulicht:
data = [1, 2, 3] it = iter(data) next(it) # => 1 next(it) # => 2 next(it) # => 3 next(it) # => StopIteration
Wenn der Iterator verbraucht wird, erhöht er sich eine StopIteration-Ausnahme, wenn keine weiteren Elemente zum Ausgeben vorhanden sind. Im Kontext einer for-Schleife führt diese Ausnahme dazu, dass die Schleife beim ersten Mal beendet wird.
Problemumgehungen und alternative Ansätze
Wenn Sie dieselben Daten durchlaufen müssen Mehrere Male stehen mehrere Problemumgehungen zur Verfügung:
1. Erstellen Sie eine Liste:
Sie können die Elemente des Iterators in einer Liste speichern, die dann beliebig oft wiederholt werden kann:
data = list(it)
2 . Verwenden Sie tee() für unabhängige Iteratoren:
Wenn Ihr Iterator eine große Anzahl von Elementen verarbeitet, kann das Erstellen einer Liste ineffizient sein. Mit der Funktion itertools.tee() können Sie mehrere unabhängige Iteratoren aus einer einzigen Quelle erstellen:
import itertools it1, it2 = itertools.tee(data, 2) # create as many as needed
Jeder dieser Iteratoren kann separat durchlaufen werden, ohne dass sich dies auf die anderen auswirkt.
3. In eine Sequenz konvertieren:
Einige Iteratoren, wie z. B. Mengen, können mithilfe von Funktionen wie list() oder tuple() in Sequenzen konvertiert werden. Durch diese Konvertierung wird ein neues Objekt erstellt, das mehrfach iteriert werden kann:
data = list(sorted(my_set))
Indem Sie das Verbrauchsverhalten von Iteratoren verstehen und geeignete Problemumgehungen implementieren, können Sie die Vorteile iterierbarer Objekte nutzen und gleichzeitig sicherstellen, dass Sie über die Daten verfügen, die Sie benötigen Notwendigkeit mehrerer Iterationen.
Das obige ist der detaillierte Inhalt vonWarum kann ich einen Iterator nicht mehrmals durchlaufen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!