Итерация по всем парам последовательных элементов в списке
приведенный список
l = [1, 7, 3, 5]
Я хочу, чтобы перебрать все пары последовательных элементов списка (1,7), (7,3), (3,5)
, т. е.
for i in xrange(len(l) - 1):
x = l[i]
y = l[i + 1]
# do something
Я хотел бы сделать это более компактным способом, например
for x, y in someiterator(l): ...
есть ли способ сделать это с помощью встроенных итераторов Python? Я уверен, что itertools
модуль должен иметь решение, но я просто не могу понять это.
5 ответов:
просто использовать zip
>>> l = [1, 7, 3, 5] >>> for first, second in zip(l, l[1:]): ... print first, second ... 1 7 7 3 3 5
как было предложено, вы можете рассмотреть возможность использования
посмотреть
pairwise
на itertools рецепты:http://docs.python.org/2/library/itertools.html#recipesцитирую оттуда:
def pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), ..." a, b = tee(iterable) next(b, None) return izip(a, b)
Общая Версия
общая версия, которая дает кортежи любого заданного положительного естественного размера, может выглядеть так:
def nwise(iterable, n=2): iters = tee(iterable, n) for i, it in enumerate(iters): next(islice(it, i, i), None) return izip(*iters)
Я бы создал общий
grouper
генератор, такойdef grouper(input_list, n = 2): for i in xrange(len(input_list) - (n - 1)): yield input_list[i:i+n]
пример выполнения 1
for first, second in grouper([1, 7, 3, 5, 6, 8], 2): print first, second
выход
1 7 7 3 3 5 5 6 6 8
пример выполнения 1
for first, second, third in grouper([1, 7, 3, 5, 6, 8], 3): print first, second, third
выход
1 7 3 7 3 5 3 5 6 5 6 8
вы могли бы использовать
zip
.>>> list(zip(range(5), range(2, 6))) [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
так же, как молния, он создает пары. Итак, чтобы смешать два списка, вы получаете:
>>> l = [1,7,3,5] >>> list(zip(l[:-1], l[1:])) [(1, 7), (7, 3), (3, 5)]
затем итерация идет как
for x, y in zip(l[:-1], l[1:]): pass
то, что ниже, очень просто/читаемо и делает эту работу, также, вероятно, наиболее эффективной.
преобразовать список в генератор (или лучше начать с iterator, чтобы звезда с):
gen = (x for x in l)
преобразовать его в пары:
[(x, gen.next()) for x in gen]
Это все, что вам нужно.
конечно, лучше сделать его генератор тоже и читать из него, как вам нужно:
( (x, gen.next()) for x in gen)