À partir d'une liste
l = [1, 7, 3, 5]
Je souhaite parcourir toutes les paires d'éléments de liste consécutifs (1,7), (7,3), (3,5)
, c.-à-d.
for i in xrange(len(l) - 1):
x = l[i]
y = l[i + 1]
# do something
Je voudrais faire cela d'une manière plus compacte, comme
for x, y in someiterator(l): ...
Y a-t-il un moyen de faire cela en utilisant les itérateurs Python intégrés? Je suis sûr que le module itertools
devrait avoir une solution, mais je ne peux pas le comprendre.
Il suffit d'utiliser Zip
>>> l = [1, 7, 3, 5]
>>> for first, second in Zip(l, l[1:]):
... print first, second
...
1 7
7 3
3 5
Comme suggéré, vous pouvez envisager d'utiliser la fonction izip
dans itertools
pour les très longues listes pour lesquelles vous ne souhaitez pas créer de nouvelle liste.
import itertools
for first, second in itertools.izip(l, l[1:]):
...
Regardez pairwise
dans les recettes d’itertools: http://docs.python.org/2/library/itertools.html#recipes
Citant à partir de là:
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
Une version générale
Une version générale, qui donne des n-uplets de toute taille naturelle positive, peut ressembler à ceci:
def nwise(iterable, n=2):
iters = tee(iterable, n)
for i, it in enumerate(iters):
next(islice(it, i, i), None)
return izip(*iters)
Je créerais un générateur générique grouper
, comme celui-ci
def grouper(input_list, n = 2):
for i in xrange(len(input_list) - (n - 1)):
yield input_list[i:i+n]
Exemple de cycle 1
for first, second in grouper([1, 7, 3, 5, 6, 8], 2):
print first, second
Sortie
1 7
7 3
3 5
5 6
6 8
Exemple de cycle 1
for first, second, third in grouper([1, 7, 3, 5, 6, 8], 3):
print first, second, third
Sortie
1 7 3
7 3 5
3 5 6
5 6 8
Vous pouvez utiliser une Zip
.
>>> list(Zip(range(5), range(2, 6)))
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
Tout comme une fermeture à glissière, il crée des paires. Donc, pour mélanger vos deux listes, vous obtenez:
>>> l = [1,7,3,5]
>>> list(Zip(l[:-1], l[1:]))
[(1, 7), (7, 3), (3, 5)]
Puis itération va comme
for x, y in Zip(l[:-1], l[1:]):
pass
Généraliser l'approche de sberry à nwise avec compréhension:
def nwise(lst, k=2):
return list(Zip(*[lst[i:] for i in range(k)]))
Par exemple
nwise(list(range(10)),3)
[(0, 1, 2), (1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6), (5, 6, 7 ), (6, 7, 8), (7, 8, 9)]