Ось відповідний приклад із документів модуля 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)
Для Python 2, вам потрібно itertools.izipзамість 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)
Як це працює:
По- перше, два паралельних ітератори, aі bстворюються (на tee()виклик), і вказує на перший елемент оригіналу ітерацію. Другий ітератор bпереміщується на 1 крок вперед ( next(b, None)виклику). У цей момент aвказує на s0 і bвказує на s1. Обидва aі bможуть самостійно переходити оригінальний ітератор - функція izip приймає два ітератори та робить пари повернених елементів, просуваючи обидва ітератора з однаковим темпом.
Одне застереження: tee()функція виробляє два ітератори, які можуть просуватися незалежно один від одного, але це коштує дорого. Якщо один з ітераторів просувається далі, ніж інший, тоді tee() потрібно зберегти споживані елементи в пам’яті, поки другий ітератор теж їх не заповнить (він не може «перемотати» початковий ітератор). Тут це не має значення, оскільки один ітератор лише на 1 крок попереду іншого, але загалом таким чином легко використовувати багато пам'яті.
А оскільки tee()може приймати nпараметр, він також може бути використаний для більш ніж двох паралельних ітераторів:
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)