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.izip
au 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, a
et b
sont créés (l' tee()
appel), les deux pointant vers le premier élément de la iterable originale. Le deuxième itérateur, b
est déplacé d'un pas en avant (l' next(b, None)
appel). À ce stade, a
pointe vers s0 et b
pointe vers s1. Les deux a
et b
peuvent 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 n
paramè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)