Voici un exemple pertinent tiré de la documentation du module 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)
Pour Python 2, vous avez besoin itertools.izipau lieu de 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)
Comment ça marche:
Tout d' abord, deux itérateurs parallèles, aet bsont créés (l' tee()appel), les deux pointant vers le premier élément de la iterable originale. Le deuxième itérateur, best déplacé d'un pas en avant (l' next(b, None)appel). À ce stade, apointe vers s0 et bpointe vers s1. Les deux aet bpeuvent parcourir l'itérateur d'origine indépendamment - la fonction izip prend les deux itérateurs et crée des paires d'éléments retournés, en faisant avancer les deux itérateurs au même rythme.
Une mise en garde: la tee()fonction produit deux itérateurs qui peuvent avancer indépendamment l'un de l'autre, mais cela a un coût. Si l'un des itérateurs avance plus loin que l'autre, alorstee() doit conserver les éléments consommés en mémoire jusqu'à ce que le deuxième itérateur les reprenne également (il ne peut pas «rembobiner» l'itérateur d'origine). Ici, cela n'a pas d'importance car un itérateur n'a qu'une longueur d'avance sur l'autre, mais en général, il est facile d'utiliser beaucoup de mémoire de cette façon.
Et comme tee()peut prendre un nparamètre, cela peut également être utilisé pour plus de deux itérateurs parallèles:
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)