[通常,我发现需要成对处理列表。我想知道哪种方法是有效的pythonic方法,并在Google上找到了它:
pairs = zip(t[::2], t[1::2])
我认为这已经足够了pythonic,但是在最近涉及idioms versus efficiency的讨论之后,我决定进行一些测试:
import time
from itertools import islice, izip
def pairs_1(t):
return zip(t[::2], t[1::2])
def pairs_2(t):
return izip(t[::2], t[1::2])
def pairs_3(t):
return izip(islice(t,None,None,2), islice(t,1,None,2))
A = range(10000)
B = xrange(len(A))
def pairs_4(t):
# ignore value of t!
t = B
return izip(islice(t,None,None,2), islice(t,1,None,2))
for f in pairs_1, pairs_2, pairs_3, pairs_4:
# time the pairing
s = time.time()
for i in range(1000):
p = f(A)
t1 = time.time() - s
# time using the pairs
s = time.time()
for i in range(1000):
p = f(A)
for a, b in p:
pass
t2 = time.time() - s
print t1, t2, t2-t1
这些是我计算机上的结果:
1.48668909073 2.63187503815 1.14518594742
0.105381965637 1.35109519958 1.24571323395
0.00257992744446 1.46182489395 1.45924496651
0.00251388549805 1.70076990128 1.69825601578
如果我正确解释了它们,那应该意味着在Python中实现列表,列表索引和列表切片非常有效。这是令人安慰和意外的结果。
还有另一种“更好”的成对遍历列表的方法吗?
请注意,如果列表中元素的数量为奇数,则最后一个元素将不在任何对中。
哪种方法可以确保包括所有元素?
我从测试答案中添加了这两个建议:
def pairwise(t):
it = iter(t)
return izip(it, it)
def chunkwise(t, size=2):
it = iter(t)
return izip(*[it]*size)
这些是结果:
0.00159502029419 1.25745987892 1.25586485863
0.00222492218018 1.23795199394 1.23572707176
最pythonic,非常有效:
pairs = izip(t[::2], t[1::2])
最有效且非常pythonic:
pairs = izip(*[iter(t)]*2)
花了我一段时间,第一个答案使用了两个迭代器,而第二个答案使用了一个迭代器。
为了处理具有奇数个元素的序列,建议增加原始序列,增加一个元素(None
),该元素与之前的最后一个元素配对,itertools.izip_longest()
可以实现。 >
请注意,在Python 3.x中,zip()
的行为与itertools.izip()
相同,itertools.izip()
消失了。
[通常,我发现需要成对处理列表。我想知道哪种方法是有效的pythonic方法,并在Google上找到了它:pair = zip(t [:: 2],t [1 :: 2])我以为...
pairs = zip(t[::2], t[1::2])
是最好的解决方案,因为它最容易阅读(在Python 3中,zip
自动返回一个迭代器而不是列表)。pairwise
函数,但使用iter
和lambda
闭包。它不使用itertools
模块,也不支持fillvalue
。我把它放在这里是因为有人可能会觉得有趣:还有另一种“更好”的成对遍历列表的方法吗?
>>> my_list = [1,2,3,4,5,6,7,8,9,10]
>>> my_pairs = list()
>>> while(my_list):
... a = my_list.pop(0); b = my_list.pop(0)
... my_pairs.append((a,b))
...
>>> print(my_pairs)
[(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]