35

これを行うためのより Pythonic な方法があるはずだと確信していますが、思いつきません。2 次元のリストを 1 次元のリストにマージするにはどうすればよいですか? zip/map に似ていますが、2 つ以上のイテレータがあります。

例 - 次のリストがあります。

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配列のすべての「線」が同じ長さであるかどうかをチェックしないことを除いて、互いに追加できるなど.それを行うより良い方法は何ですか?

4

8 に答える 8

71
[sum(a) for a in zip(*array)]
于 2008-11-04T21:16:39.117 に答える
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)]

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]
于 2008-11-04T21:33:47.257 に答える
14

別の方法:

map(sum, zip(*array))
于 2008-11-05T15:31:04.087 に答える
8

この種のことをたくさん行っている場合は、について学びたいと思うでしょうscipy

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

すべての配列サイズが自動的にチェックされます。合計は純粋な C で行われるため、非常に高速です。 scipy配列はメモリ効率も非常に優れています。

欠点は、かなり複雑なサードパーティ モジュールに依存していることです。しかし、これは多くの目的にとって非常に良いトレードオフです。

于 2008-11-05T15:24:08.983 に答える
3

ファイブベルに同意しますが、Numpyを使用することもできます。これは、配列のようなもののより小さく(より迅速なインポート)、より一般的な実装です。(実際には、scipyの依存関係です)。これらは、言われているように、この種の操作を処理する場合に「使用する必要がある」優れたツールです。

于 2011-02-25T04:45:31.813 に答える
2

ゲームに遅れて、それは他のいくつかほど良い答えではありませんが、私はそれがちょっとかわいいと思いました:

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

sum(1,2,3)うまくいかないのは残念です。もしそうなら、私たちはlambdaそこにあるばかげたものを取り除くことができますが、それは要素のどれが合計の「始まり」であるかを識別するのを難しくすると思います. 多くのスクリプトを壊すキーワードのみの引数にそれを変更する必要があります...まあ。私たちは一緒に暮らすだけだと思いますlambda

于 2012-11-05T21:04:10.277 に答える
0

[zip(*配列)内のaの合計(a)]

私はすきです。オブジェクトをアイテムのリストにインターリーブするために関連するものが必要でしたが、同様のものを思いつきましたが、長さのリストがより簡潔になりました。

sum(zip(*array),())

たとえば、2 つのリストをインターリーブします。

a = [1,2,3]
b = ['a','b','c']
sum(zip(a,b),())
(1, 'a', 2, 'b', 3, 'c')
于 2015-04-03T13:55:00.377 に答える