问题:用列表输出而不是元组压缩
从两个列表中选择列表的最快,最优雅的方法是什么?
我有
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,我的问题是是否已经实现了某些功能。否也是答案。
回答 0
如果您要压缩2个以上的列表(就此而言,甚至压缩2个),一种可读的方式将是:
[list(a) for a in zip([1,2,3], [4,5,6], [7,8,9])]
这使用列表推导并将列表(元组)中的每个元素转换为列表。
回答 1
您自己几乎已经有了答案。不要使用map
代替zip
。使用map
AND zip
。
您可以将地图和zip结合使用,以实现优雅,实用的方法:
list(map(list, zip(a, b)))
zip
返回一个元组列表。map(list, [...])
调用list
列表中的每个元组。list(map([...])
将地图对象变成可读列表。
回答 2
我喜欢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
回答 3
我通常不喜欢使用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]]
但是,映射被认为是非Python的,仅应用于性能调整。
回答 4
这个怎么样?
>>> 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]]
回答 5
使用numpy
优雅的定义可能会令人质疑,但是,如果您要numpy
创建数组并将其转换为列表(如果需要…),则可能非常实用,即使使用map
函数或列表理解相比效率不高。
import numpy as np
a = b = range(10)
zipped = zip(a,b)
result = np.array(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()
回答 6
我想列表理解将是非常简单的解决方案。
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]]