Hier ist ein relevantes Beispiel aus den Dokumenten des itertools- Moduls:
import itertools
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = itertools.tee(iterable)
next(b, None)
return zip(a, b)
Für Python 2 benötigen Sie itertools.izipanstelle von zip:
import itertools
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = itertools.tee(iterable)
next(b, None)
return itertools.izip(a, b)
So funktioniert das:
Zuerst werden zwei parallel Iteratoren, aund bwerden erstellt (der tee()Anruf), die beide nach dem ersten Element des ursprünglichen iterable. Der zweite Iterator bwird 1 Schritt vorwärts (der next(b, None)Aufruf) verschoben . An dieser Stelle azeigt auf s0 und bzeigt auf s1. Beide aund bkönnen den ursprünglichen Iterator unabhängig voneinander durchlaufen - die izip-Funktion verwendet die beiden Iteratoren und erstellt Paare der zurückgegebenen Elemente, wobei beide Iteratoren im gleichen Tempo weiterentwickelt werden.
Eine Einschränkung: Die tee()Funktion erzeugt zwei Iteratoren, die unabhängig voneinander vorrücken können, jedoch mit Kosten verbunden sind. Wenn einer der Iteratoren weiter voranschreitet als der andere, tee() müssen die verbrauchten Elemente im Speicher bleiben, bis der zweite Iterator sie ebenfalls verbraucht (der ursprüngliche Iterator kann nicht zurückgespult werden). Hier spielt es keine Rolle, da ein Iterator dem anderen nur einen Schritt voraus ist, aber im Allgemeinen ist es einfach, auf diese Weise viel Speicher zu verwenden.
Und da tee()ein nParameter verwendet werden kann, kann dieser auch für mehr als zwei parallele Iteratoren verwendet werden:
def threes(iterator):
"s -> (s0,s1,s2), (s1,s2,s3), (s2, s3,4), ..."
a, b, c = itertools.tee(iterator, 3)
next(b, None)
next(c, None)
next(c, None)
return zip(a, b, c)