Pythonでのリストのマージ/追加


Answers

[zip(* array)の値のsum(value)]はかなり標準的です。

これはあなたがそれを理解するのに役立つでしょう:

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

私はこれを行うもっとPythonの方法があるはずだと確信していますが、私は考えることができません:どのように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配列のすべての「線」が同じ長さであるかどうかをチェックしないこと以外に、お互いに追加することなどができます。これを行うにはどうすればよいでしょうか?




ゲームに遅れて、それは他のいくつかのものと同じくらい良い答えではありませんが、私はそれがかわいいと思った:

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

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




あなたがこのようなことをたくさんしているなら、あなたはscipyについて学びたいと思っています

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

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

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




これを簡単に行うことができます:

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

この方法でリストを繰り返し処理する場合は、 itertoolsモジュールのchainを使用できます。

from itertools import chain

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