使用 list 输出而不是 tuple 压缩

从两个列表中列出列表的最快和最优雅的方法是什么?

是的

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,我的问题是是否已经实现了一些东西。没有也是一个答案。

121789 次浏览

我一般不喜欢用 lambda 但是..。

>>> a = [1, 2, 3, 4, 5]
>>> b = [6, 7, 8, 9, 10]
>>> c = lambda a, b: [list(c) for c in zip(a, b)]
>>> c(a, b)
[[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]

如果你需要额外的速度,地图会稍微快一点:

>>> d = lambda a, b: map(list, zip(a, b))
>>> d(a, b)
[[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]

然而,map 被认为是非 pythonic 的,只能用于性能调优。

如果你正在压缩超过2个列表(甚至只有2个) ,一个可读的方法是:

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

这使用一个列表内涵到 对列表中的每个元素(元组)应用 list,将它们转换成列表。

这个怎么样?

>>> def list_(*args): return list(args)


>>> map(list_, range(5), range(9,4,-1))
[[0, 9], [1, 8], [2, 7], [3, 6], [4, 5]]

或者更好:

>>> def zip_(*args): return map(list_, *args)
>>> zip_(range(5), range(9,4,-1))
[[0, 9], [1, 8], [2, 7], [3, 6], [4, 5]]

Python 3的更新: 在 Python3中,map 返回迭代器而不是列表。这是我测试过的几个选项中最快的(使用 timeit模块计时) :

[list(t) for t in zip(*lists)]

我喜欢 zip 函数的优雅,但是在操作符模块中使用 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

你自己也差不多有答案了。不要用 map代替 zip。用 map 还有 zip

您可以使用 map 和 zip 来实现一种优雅的、功能性的方法:

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

zip返回元组列表。map(list, [...])对列表中的每个元组调用 listlist(map([...])将映射对象转换为可读列表。

列表内涵是个非常简单的解决方案。

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


b=[7,8,9,10,11,12]


x = [[i, j] for i, j in zip(a,b)]


print(x)


output : [[1, 7], [2, 8], [3, 9], [4, 10], [5, 11], [6, 12]]

用麻木

优雅的定义可能很值得怀疑,但如果你使用的是 numpy,那么创建一个数组并将其转换为 list (如果需要的话...)可能非常实用,尽管与使用 map函数或列表内涵相比效率不高。

import numpy as np
a = b = range(10)
zipped = zip(a,b)
# result = np.array(zipped).tolist() Python 2.7
result = np.array(list(zipped)).tolist()
Out: [[0, 0],
[1, 1],
[2, 2],
[3, 3],
[4, 4],
[5, 5],
[6, 6],
[7, 7],
[8, 8],
[9, 9]]

否则跳过 zip函数,你可以直接使用 np.dstack:

np.dstack((a,b))[0].tolist()