在Python中合并/添加列表

我敢肯定,应该有一个更Pythonic这样做的方式 – 但我想不出一个:我怎样才能将一个二维列表合并到一维列表? 有点像zip / map,但有两个以上的迭代器。

示例 – 我有以下列表:

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数组中的所有“行”是否具有相同的长度,是否可以添加到彼此等等。有什么更好的方法来做到这一点?

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

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

zip()是一个内置函数

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

由zip返回的列表的每个元素都是您想要的一组数字。

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

另一种方法:

 map(sum, zip(*array)) 

如果你做了很多这样的事情,你想了解scipy

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

所有数组大小都会自动检查。 总和是用纯C做的,所以速度非常快。 scipy数组也是非常有效的内存。

缺点是你依赖于相当复杂的第三方模块。 但是这对于许多目的来说是一个很好的折衷。

同意fivebells,但你也可以使用Numpy,这是一个更小的(更快的导入)和更类似arrays的东西的通用实现。 (实际上,这是一个scipy的依赖)。 如前所述,如果你处理这种操作,这些工具是一个“必须使用”的工具。

在比赛结束后,这个问题并不像其他一些问题那么好,但是我觉得这很可爱:

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

sum(1,2,3)不起作用太糟糕了。 如果是这样的话,我们可以消除那里的愚蠢的lambda ,但是我想这会使得难以辨别哪个元素(如果有的话)是总和的“开始”。 你必须改变这个关键字的唯一论点,这将打破很多脚本…哦,好吧。 我想我们只会和lambda生活。

[总和(一)在拉链(*arrays)]

我喜欢。 我需要一些相关的东西来交叉项目列表中的对象,提出了类似的,但更简洁的甚至长度列表:

 sum(zip(*array),()) 

例如交错两个列表:

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

你可以简单地做到这一点:

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

如果你想以这种方式迭代列表,你可以使用itertools模块的链接:

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