Подтвердить что ты не робот

Объединение/добавление списков в 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-массиве иметь одинаковую длину, могут быть добавлены друг к другу и т.д. Что было бы лучшим способом сделать это?

4b9b3361

Ответ 1

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

Ответ 2

[сумма (значение) для значения в 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]

Ответ 3

Альтернативный способ:

map(sum, zip(*array))

Ответ 4

Если вы делаете много такого, вы хотите узнать о scipy.

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

Все размеры массива проверяются автоматически. Сумма делается в чистом C, поэтому она очень быстрая. Массивы scipy также очень эффективны с точки зрения памяти.

Недостатком является то, что вы зависите от довольно сложного стороннего модуля. Но это очень хороший компромисс для многих целей.

Ответ 5

Согласитесь с пятью колонами, но вы также можете использовать Numpy, который является меньшим (более быстрый импорт) и более общей реализацией массива. (на самом деле, это зависимость от scipy). Это отличные инструменты, которые, как уже было сказано, "должны использовать", если вы имеете дело с такими манипуляциями.

Ответ 6

Поздно к игре, и это не так хорошо, как некоторые из других, но я подумал, что это было мило:

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

Это слишком плохо, что sum(1,2,3) не работает. Если бы это было так, мы могли бы устранить там глупый lambda, но, полагаю, это затруднило бы распознать, какие (если есть) элементы являются "началом" суммы. Вы должны были бы изменить это только на ключевое слово, которое нарушило бы множество скриптов... О, хорошо. Думаю, мы будем жить с lambda.

Ответ 7

[sum (a) для a в zip (* array)]

Мне это нравится. Мне нужно что-то связанное для перемежения объектов в список элементов, придумал что-то похожее, но более сжатое для списков длины:

sum(zip(*array),())

например, чередуя два списка:

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

Ответ 8

Вы можете просто сделать это:

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

Если вы хотите итерации по спискам таким образом, вы можете использовать chain модуля itertools:

from itertools import chain

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