2011-12-04 32 views
40

從兩個列表中完成列表清單的最快和最優雅的方式是什麼?帶有列表輸出而不是元組的郵件列表

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

我想使用的地圖,而不是拉鍊,但我不知道是否有一些標準庫的方法作爲第一個論點。

我可以定義我自己的功能,並使用地圖,我的問題是如果已經實現了一些東西。 也是一個答案。

+1

那麼,你真的**需要**列表嗎?你將如何處理結果? –

+7

一個例子是sklearn,其中很多時候數據必須以這種方式組織。 –

回答

52

如果您荏苒超過2名列表(甚至只有2,對於這個問題),可讀的方法是:

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

這將使用列表理解,每個元素在列表轉換(元組)到列表中。

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

但是,地圖被認爲是unpythonic和只能用於性能調整。

+3

什麼'lambda'在這裏添加?我們可以直接編寫表達式而不是調用函數(它實際上並不複雜),即使想要一個函數,也可以在兩行中輕鬆定義(如果返回鍵已損壞或者您瘋了) 。另一方面,如果第一個參數是一個普通函數(而不是'lambda'),'map'就完全沒問題。 – delnan

+1

他問了一個函數。但我同意 - 可能更好只是爲了支付額外的費用。至於地圖,我認爲列表理解幾乎總是更清晰。 –

+1

我會推薦通過'lambda'的'map'。所以'map(list,zip(a,b))'。列表解析可能會更清晰一些,但地圖應該更快(未經測試) – inspectorG4dget

1

這個怎麼樣?

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

對我來說,這似乎是比其他人更好的答案,因爲我們正在通過不做一個zip和直接創建一個列表來減少一步。棒極了 –

12

我愛的拉鍊功能的風采,但使用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 

我預計拉鍊要快,但itemgetter方法獲得由一個長鏡頭:

Using zip 
6.1550450325 
Using itemgetter 
0.768098831177 
+2

這是OP試圖做的轉置。你能否更新你的文章以反映這一點?即,OP將兩個列表轉換爲列表或任意數量的對。您將任意數量的對轉換爲一對列表。 –

+0

這是測量哪個python版本? – Moberg

+0

我不記得了,它是在兩年前,但最有可能的2.6或2.7。我想你可以複製代碼並在你自己的版本/平臺上試用。 – kslnet

12

你幾乎擁有自己的答案。請勿使用map而不要使用zip。使用mapzip

您可以使用地圖拉鍊沿着一個優雅,功能的方法:

map(list, zip(a, b)) 

zip返回一個元組列表。 map(list, [...])在列表中的每個元組上調用list

0

列表理解將是非常簡單的解決方案,我猜。

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