Tim Pietzcker
Tim Pietzcker

Reputation: 336118

Merging/adding lists in Python

I'm pretty sure there should be a more Pythonic way of doing this - but I can't think of one: How can I merge a two-dimensional list into a one-dimensional list? Sort of like zip/map but with more than two iterators.

Example - I have the following list:

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

I want to have

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

So far what I've come up with is:

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

But that doesn't look very elegant/Pythonic to me. Aside from not checking if all the "lines" in the 2D array are of the same length, can be added to each other, etc. What would be a better way to do it?

Upvotes: 35

Views: 23378

Answers (8)

Saksham Varma
Saksham Varma

Reputation: 2130

You can simply do this:

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

If you wish to iterate through lists in this fashion, you can use chain of the itertools module:

from itertools import chain

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

Upvotes: 0

F1Rumors
F1Rumors

Reputation: 948

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

I like that. I needed something related for interleaving objects in to a list of items, came up with something similar but more concise for even length lists:

sum(zip(*array),())

for example, interleaving two lists:

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

Upvotes: 0

mgilson
mgilson

Reputation: 309841

Late to the game, and it's not as good of an answer as some of the others, but I thought it was kind of cute:

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

it's too bad that sum(1,2,3) doesn't work. If it did, we could eliminate the silly lambda in there, but I suppose that would make it difficult to discern which (if any) of the elements is the "start" of the sum. You'd have to change that to a keyword only arguement which would break a lot of scripts ... Oh well. I guess we'll just live with lambda.

Upvotes: 2

heltonbiker
heltonbiker

Reputation: 27575

Agree with fivebells, but you could also use Numpy, which is a smaller (quicker import) and more generic implementation of array-like stuff. (actually, it is a dependency of scipy). These are great tools which, as have been said, are a 'must use' if you deal with this kind of manipulations.

Upvotes: 3

ngn
ngn

Reputation: 7892

An alternative way:

map(sum, zip(*array))

Upvotes: 14

Alex Coventry
Alex Coventry

Reputation: 70819

If you're doing a lot of this kind of thing, you want to learn about scipy.

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

All array sizes are checked for you automatically. The sum is done in pure C, so it's very fast. scipy arrays are also very memory efficient.

The drawback is you're dependent on a fairly complex third-party module. But that's a very good tradeoff for many purposes.

Upvotes: 8

Charles Merriam
Charles Merriam

Reputation: 20500

[sum(value) for value in zip(*array)] is pretty standard.

This might help you understand it:

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

The unary star is not an operator by itself. It unwraps array elements into arguments into function calls.

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

zip() is a built-in function

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

each element for the list returned by zip is a set of numbers you want.

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

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

Upvotes: 63

Ned Batchelder
Ned Batchelder

Reputation: 375504

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

Upvotes: 71

Related Questions