2008-11-04 62 views
33

我很確定應該有更多的Pythonic這樣做 - 但我想不出一個:我如何將一個二維列表合併到一維列表中?有點像zip/map,但有兩個以上的迭代器。在Python中合併/添加列表

例子 - 我有以下列表:

array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 

我想有

result = [12, 15, 18] # [1+4+7, 2+5+8, 3+6+9] 

到目前爲止,我想出是:

def add_list(array): 
    number_items = len(array[0]) 
    result = [0] * number_items 
    for index in range(number_items): 
     for line in array: 
      result[index] += line[index] 
    return result 

但是,對我來說看起來不太優雅/ Pythonic。除了不檢查2D數組中的所有「行」是否具有相同的長度,可以相互添加等等,這將是更好的方法嗎?

回答

69
[sum(a) for a in zip(*array)] 
63

[zip(* array)中的值的總和(值)]非常標準。

這可以幫助你瞭解它:

In [1]: array=[[1, 2, 3], [4, 5, 6], [7, 8, 9]] 

In [2]: array 
Out[2]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 

In [3]: *array 
------------------------------------------------------------ 
    File "<ipython console>", line 1 
    *array 
    ^
<type 'exceptions.SyntaxError'>: invalid syntax 

一元星本身不是運營商。它將數組元素展開爲函數調用的參數。

In [4]: zip(*array) 
Out[4]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)] 

拉鍊()是一個內置功能

In [5]: zip(*array)[0] 
Out[5]: (1, 4, 7) 

由拉鍊返回的列表中的每個元素是一組你想要的數字。

In [6]: sum(zip(*array)[0]) 
Out[6]: 12 

In [7]: [sum(values) for values in zip(*array)] 
Out[7]: [12, 15, 18] 
8

如果你做了很多這樣的事情,你想了解scipy.

>>> import scipy 
>>> sum(scipy.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])) 
array([12, 15, 18]) 

所有的數組大小自動爲您檢查。總和是用純C完成的,所以速度非常快。 scipy數組也是非常有效的內存。

缺點是你依賴於相當複雜的第三方模塊。但是這對於許多目的來說是一個很好的折衷。

14

的另一種方法:

map(sum, zip(*array)) 
3

同意fivebells,但你也可以使用numpy的,這是一個較小的(更快的進口)以及更通用的實現的陣列一樣的東西。 (實際上,它是scipy的依賴)。如前所述,如果你處理這種操作,這些工具是'必須使用'的。

2

後期的遊戲,它不是那麼好回答,因爲一些其他的,但我認爲這是一種可愛:

map(lambda *x:sum(x),*array) 

這太糟糕了,sum(1,2,3)不起作用。如果是的話,我們可以消除那裏的愚蠢lambda,但是我想這會讓人難以辨別哪些元素(如果有的話)是總和的「開始」。你必須改變這個關鍵字唯一的爭論,這將打破很多腳本......哦,好吧。我想我們只能跟lambda住在一起。

0

[總和(a)用於一個在拉鍊(*陣列)]

我喜歡這樣。我需要到項目列表交織的對象有關的東西,想出了類似但更簡潔甚至長名單的東西:

sum(zip(*array),()) 

例如,交織兩個列表:

a = [1,2,3] 
b = ['a','b','c'] 
sum(zip(a,b),()) 
(1, 'a', 2, 'b', 3, 'c') 
+0

嗯,雖然有趣,這不是真正的答案(因此可能會吸引downvotes)。例如,您可以問「我如何交錯幾個列表?」這個問題。並自己回答。也許使用一個使用兩個以上列表的例子,否則有人會建議`「,」。join(a)`。 – 2015-04-03 14:45:49

0

你可以簡單地做到這一點:

print [sum(x) for x in zip(*array)] 

如果您希望通過列表以這種方式進行迭代,你可以使用chainitertools模塊:

from itertools import chain 

for x in array.chain.from_iterable(zip(*array)): 
    print x 
# prints 1, 4, 7, 2, 5, 8, ...