在Python中以列表(循环方式)遍历对

2024-05-13 19:02:43 发布

您现在位置:Python中文网/ 问答频道 /正文

问题很简单,我想遍历列表中的每个元素,并成对遍历下一个元素(用第一个元素包装最后一个元素)。

我考虑过两种不合乎逻辑的方法:

def pairs(lst):
    n = len(lst)
    for i in range(n):
        yield lst[i],lst[(i+1)%n]

以及:

def pairs(lst):
    return zip(lst,lst[1:]+[lst[:1]])

预期产量:

>>> for i in pairs(range(10)):
    print i

(0, 1)
(1, 2)
(2, 3)
(3, 4)
(4, 5)
(5, 6)
(6, 7)
(7, 8)
(8, 9)
(9, 0)
>>> 

有什么建议可以用更像Python的方式来做这个吗?也许有一个我没听说过的预定义函数?

另外,一个更通用的n-折叠(用三重奏、四重奏等代替成对的)版本可能会很有趣。


Tags: 方法in元素列表forlenreturndef
3条回答

我,一如既往,喜欢T恤:

from itertools import tee, izip, chain

def pairs(iterable):
    a, b = tee(iterable)
    return izip(a, chain(b, [next(b)]))
def pairs(lst):
    i = iter(lst)
    first = prev = item = i.next()
    for item in i:
        yield prev, item
        prev = item
    yield item, first

适用于任何非空序列,不需要索引。

我为自己编写了元组通用版本,我喜欢第一个版本,因为它简单易懂,我看得越多,感觉越像Python。。。毕竟,还有什么比一行压缩、星号参数扩展、列表理解、列表切片、列表连接和“范围”更像Pythonic呢?

def ntuples(lst, n):
    return zip(*[lst[i:]+lst[:i] for i in range(n)])

itertools版本应该足够高效,即使对于大列表。。。

from itertools import *
def ntuples(lst, n):
    return izip(*[chain(islice(lst,i,None), islice(lst,None,i)) for i in range(n)])

以及非可转位序列的版本:

from itertools import *
def ntuples(seq, n):
    iseq = iter(seq)
    curr = head = tuple(islice(iseq, n))
    for x in chain(iseq, head):
        yield curr
        curr = curr[1:] + (x,)

无论如何,谢谢大家的建议!:-)

相关问题 更多 >