我不敢相信这无处可寻,但是:我想要数组中的所有连续对,包括最后一个元素和第一个元素。我试过:
[(a, b) for a, b in zip(list, list[1:])]
Run Code Online (Sandbox Code Playgroud)
什么是最 Pythonic 和最有效的方式来做到这一点?
Eri*_*nil 12
另一种方法是使用模从最后一个元素跳回到第一个元素:
l = [1,2,3,4,5,6]
n = len(l)
[(l[i], l[(i+1) % n]) for i in range(n)]
Run Code Online (Sandbox Code Playgroud)
它返回:
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 1)]
Run Code Online (Sandbox Code Playgroud)
Jea*_*bre 10
您只需要将第一个元素添加到第二个列表中:
l = [1,2,3,4,5,6]
r = [(a, b) for a, b in zip(l, l[1:]+l[:1])]
Run Code Online (Sandbox Code Playgroud)
结果:
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 1)]
Run Code Online (Sandbox Code Playgroud)
旁白:“pythonic”也意味着不用list作变量名。
变体:使用itertools.ziplongest代替zip并填充第一个元素(作为奖励,也适用于numpy数组,因为没有添加):
import itertools
r = [(a, b) for a, b in itertools.zip_longest(l, l[1:], fillvalue=l[0])]
Run Code Online (Sandbox Code Playgroud)
这是使用 a 的另一种方法collections.deque:
>>> from collections import deque
>>> x = list(range(7))
>>> d = deque(x)
>>> d.rotate(-1)
>>> list(zip(x,d))
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 0)]
>>>
Run Code Online (Sandbox Code Playgroud)
我并不是在质疑其中一些答案的酷炫,但似乎没有人对它们进行计时,并且就“Pythonic”而言,与仅将圆形部分附加或扩展到最后相比,它们可能会变得有些晦涩。
l = xrange(1, 10000)
def simple_way(list_input):
a = [(list_input[i], list_input[i+1]) for i in xrange(len(list_input)-1)]
a.append((list_input[-1], list_input[0]))
return a
timeit simple_way(l)
1000 loops, best of 3: 1.14 ms per loop
def top_rated_answer(list_input):
n = len(list_input)
a = [(list_input[i], list_input[(i+1) % n]) for i in xrange(n)]
return a
timeit top_rated_answer(l)
1000 loops, best of 3: 1.37 ms per loop
Run Code Online (Sandbox Code Playgroud)