用列表输出而不是元组压缩

问题:用列表输出而不是元组压缩

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

我有

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,我的问题是是否已经实现了某些功能。也是答案。

What is the fastest and most elegant way of doing list of lists from two lists?

I have

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)]

And I’d like to have

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

I was thinking about using map instead of zip, but I don’t know if there is some standard library method to put as a first argument.

I can def my own function for this, and use map, my question is if there is already implemented something. No is also an answer.


回答 0

如果您要压缩2个以上的列表(就此而言,甚至压缩2个),一种可读的方式将是:

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

这使用列表推导并将列表(元组)中的每个元素转换为列表。

If you are zipping more than 2 lists (or even only 2, for that matter), a readable way would be:

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

This uses list comprehensions and converts each element in the list (tuples) into lists.


回答 1

您自己几乎已经有了答案。不要使用map代替zip。使用map AND zip

您可以将地图和zip结合使用,以实现优雅,实用的方法:

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

zip返回一个元组列表。map(list, [...])调用list列表中的每个元组。list(map([...])将地图对象变成可读列表。

You almost had the answer yourself. Don’t use map instead of zip. Use map AND zip.

You can use map along with zip for an elegant, functional approach:

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

zip returns a list of tuples. map(list, [...]) calls list on each tuple in the list. list(map([...]) turns the map object into a readable list.


回答 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

I love the elegance of the zip function, but using the itemgetter() function in the operator module appears to be much faster. I wrote a simple script to test this:

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

I expected zip to be faster, but the itemgetter method wins by a long shot:

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的,仅应用于性能调整。

I generally don’t like using lambda, but…

>>> 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]]

If you need the extra speed, map is slightly faster:

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

However, map is considered unpythonic and should only be used for performance tuning.


回答 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]]

How about this?

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

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

Or even better:

>>> 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()

Using numpy

The definition of elegance can be quite questionable but if you are working with numpy the creation of an array and its conversion to list (if needed…) could be very practical even though not so efficient compared using the map function or the list comprehension.

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]]

Otherwise skipping the zip function you can use directly 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]]

List comprehension would be very simple solution I guess.

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]]