迭代列表中的所有连续项对

flo*_*onk 76 python iterator list

给出一个清单

l = [1, 7, 3, 5]
Run Code Online (Sandbox Code Playgroud)

我想迭代所有连续列表项对(1,7), (7,3), (3,5),即

for i in xrange(len(l) - 1):
    x = l[i]
    y = l[i + 1]
    # do something
Run Code Online (Sandbox Code Playgroud)

我想以更紧凑的方式做到这一点,比如

for x, y in someiterator(l): ...
Run Code Online (Sandbox Code Playgroud)

有没有办法使用内置的Python迭代器来做到这一点?我确定该itertools模块应该有一个解决方案,但我无法弄明白.

sbe*_*rry 114

只需使用拉链

>>> l = [1, 7, 3, 5]
>>> for first, second in zip(l, l[1:]):
...     print first, second
...
1 7
7 3
3 5
Run Code Online (Sandbox Code Playgroud)

根据建议,您可以考虑izipitertools非常长的列表中使用该函数,而不想创建新列表.

import itertools

for first, second in itertools.izip(l, l[1:]):
    ...
Run Code Online (Sandbox Code Playgroud)

  • 在Python 3中,`zip()`返回一个迭代器.更好地使用Python 3. (52认同)
  • Meh ...在Python 2中,`zip()`返回一个新列表.更好地使用`itertools.izip()`. (5认同)
  • 这会毫无理由地创建`l`(几乎所有元素)的副本. (5认同)
  • 谢谢,但不应该是`zip(l [: - 1],l [1:])`而不是`zip(l,l [1:])`? (3认同)
  • @flonk,不一定像拉链一样会尝试制作完整的组. (2认同)

Bac*_*ach 32

看一下pairwiseitertools的食谱: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)
Run Code Online (Sandbox Code Playgroud)

一般版本

产生任何给定正自然大小的元组的通用版本可能如下所示:

def nwise(iterable, n=2):                                                      
    iters = tee(iterable, n)                                                     
    for i, it in enumerate(iters):                                               
        next(islice(it, i, i), None)                                               
    return izip(*iters)   
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这种方法,因为它不会复制输入可迭代。对于 python3,只需使用“zip”而不是“izip”。 (2认同)

the*_*eye 12

我会grouper像这样创建一个通用生成器

def grouper(input_list, n = 2):
    for i in xrange(len(input_list) - (n - 1)):
        yield input_list[i:i+n]
Run Code Online (Sandbox Code Playgroud)

样品运行1

for first, second in grouper([1, 7, 3, 5, 6, 8], 2):
    print first, second
Run Code Online (Sandbox Code Playgroud)

产量

1 7
7 3
3 5
5 6
6 8
Run Code Online (Sandbox Code Playgroud)

样品运行1

for first, second, third in grouper([1, 7, 3, 5, 6, 8], 3):
    print first, second, third
Run Code Online (Sandbox Code Playgroud)

产量

1 7 3
7 3 5
3 5 6
5 6 8
Run Code Online (Sandbox Code Playgroud)