使用列表输出而非元组进行zip

136 投票
7 回答
144949 浏览
提问于 2025-04-17 07:38

从两个列表中生成列表的列表,最快最优雅的方法是什么?

我有

In [1]: a=[1,2,3,4,5,6]

In [2]: b=[7,8,9,10,11,12]

In [3]: zip(a,b)
Out[3]: [(1, 7), (2, 8), (3, 9), (4, 10), (5, 11), (6, 12)]

我想要得到

In [3]: some_method(a,b)
Out[3]: [[1, 7], [2, 8], [3, 9], [4, 10], [5, 11], [6, 12]]

我在考虑用 map 代替 zip,但我不知道有没有什么标准库的方法可以作为第一个参数。

我可以自己定义一个函数来实现这个,并使用 map,我的问题是有没有已经实现的东西。没有也是一个答案。

7 个回答

16

我很喜欢zip函数的优雅写法,但使用operator模块里的itemgetter()函数似乎要快得多。我写了一个简单的脚本来测试这个:

import time
from operator import itemgetter

list1 = list()
list2 = list()
origlist = list()
for i in range (1,5000000):
        t = (i, 2*i)
        origlist.append(t)

print "Using zip"
starttime = time.time()
list1, list2 = map(list, zip(*origlist))
elapsed = time.time()-starttime
print elapsed

print "Using itemgetter"
starttime = time.time()
list1 = map(itemgetter(0),origlist)
list2 = map(itemgetter(1),origlist)
elapsed = time.time()-starttime
print elapsed

我原本以为zip会更快,但结果itemgetter的方法快了很多:

Using zip
6.1550450325
Using itemgetter
0.768098831177
88

你几乎已经找到了答案。不要只用 map,而是要用 zip。要同时使用 mapzip

你可以把 mapzip 一起用,这样会让代码看起来更优雅,更像函数式编程的风格:

list(map(list, zip(a, b)))

zip 会返回一个包含元组的列表。然后 map(list, [...]) 会对列表中的每个元组都调用一次 list,把它们变成列表。最后 list(map([...]) 会把这个 map 对象转换成一个可读的列表。

137

如果你要把两个以上的列表合并在一起(其实就算只有两个也可以),一种比较好理解的方法是:

[list(a) for a in zip([1,2,3], [4,5,6], [7,8,9])]

这里使用了一种叫做列表推导式的写法,来对列表中的每一个元素(也就是元组)进行处理,把它们转换成列表。

撰写回答