Oto odpowiedni przykład z dokumentacji modułu itertools :
import itertools
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = itertools.tee(iterable)
next(b, None)
return zip(a, b)
W przypadku Pythona 2 itertools.izipzamiast 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)
Jak to działa:
Najpierw tworzone są dwa równoległe iteratory ai b( tee()wywołanie), oba wskazujące na pierwszy element oryginalnego iterowalnego. Drugi iterator bjest przesuwany o 1 krok do przodu ( next(b, None)wywołanie). W tym momencie awskazuje na s0 i bwskazuje na s1. Oba ai bmogą niezależnie przechodzić przez oryginalny iterator - funkcja izip przyjmuje dwa iteratory i tworzy pary zwracanych elementów, przesuwając oba iteratory w tym samym tempie.
Jedno zastrzeżenie: tee()funkcja generuje dwa iteratory, które mogą się rozwijać niezależnie od siebie, ale wiąże się to z pewnym kosztem. Jeśli jeden z iteratorów posuwa się dalej niż drugi, to tee() musi przechowywać zużyte elementy w pamięci, dopóki drugi iterator również ich nie pochłonie (nie może „przewinąć” oryginalnego iteratora). Tutaj nie ma to znaczenia, ponieważ jeden iterator jest tylko o krok przed drugim, ale ogólnie w ten sposób można łatwo wykorzystać dużo pamięci.
A ponieważ tee()może przyjmować nparametr, można go również użyć dla więcej niż dwóch równoległych iteratorów:
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)