问题描述
问题很简单,我想迭代列表的每个元素和下一个成对的元素(用第一个包裹最后一个).
The problem is easy, I want to iterate over each element of the list and the next one in pairs (wrapping the last one with the first).
我想到了两种非pythonic的方法:
I've thought about two unpythonic ways of doing it:
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)
>>>
有什么关于更 Pythonic 的方法的建议吗?也许有一个我没有听说过的预定义函数?
any suggestions about a more pythonic way of doing this? maybe there is a predefined function out there I haven't heard about?
还有一个更通用的 n-fold(使用三重奏、四重奏等,而不是对)版本可能会很有趣.
also a more general n-fold (with triplets, quartets, etc. instead of pairs) version could be interesting.
推荐答案
我自己编写了元组通用版本,我喜欢第一个,因为它优雅简洁,我越看越觉得 Pythonic我......毕竟,有什么比一个带有 zip、星号参数扩展、列表推导、列表切片、列表连接和范围"的单行更 Pythonic 的?
I've coded myself the tuple general versions, I like the first one for it's ellegant simplicity, the more I look at it, the more Pythonic it feels to me... after all, what is more Pythonic than a one liner with zip, asterisk argument expansion, list comprehensions, list slicing, list concatenation and "range"?
def ntuples(lst, n):
return zip(*[lst[i:]+lst[:i] for i in range(n)])
即使对于大型列表,itertools 版本也应该足够高效...
The itertools version should be efficient enough even for large lists...
from itertools import *
def ntuples(lst, n):
return izip(*[chain(islice(lst,i,None), islice(lst,None,i)) for i in range(n)])
还有一个用于不可索引序列的版本:
And a version for non-indexable sequences:
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,)
无论如何,谢谢大家的建议!:-)
Anyway, thanks everybody for your suggestions! :-)
这篇关于在 Python 中以列表(循环方式)迭代对的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!