35

I have a list of tuples similar to this:

l = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 0)]

I want to create a simple one-liner that will give me the following result:

r = (25, 20) or r = [25, 20] # don't care if tuple or list.

Which would be like doing the following:

r = [0, 0]
for t in l:
  r[0]+=t[0]
  r[1]+=t[1]

I am sure it is something very simple, but I can't think of it.

Note: I looked at similar questions already:

How do I sum the first value in a set of lists within a tuple?

How do I sum the first value in each tuple in a list of tuples in Python?

Community
  • 1
  • 1
Inbar Rose
  • 41,843
  • 24
  • 85
  • 131
  • 1
    possible duplicate of [Python element-wise tuple operations like sum](http://stackoverflow.com/questions/497885/python-element-wise-tuple-operations-like-sum) – Ciro Santilli OurBigBook.com Dec 19 '14 at 18:17
  • @CiroSantilli: it is not a duplicate. The question that you've linked works with *two* tuples. This question about a *list* of tuples. The transposition is the essential part of the solution. Though the answers work almost verbatim in both cases. Still `a,b` tuples and `a_list_of_tuples` are different (the diffence might be exposed in what solution is the most efficient). – jfs Dec 23 '14 at 22:33

3 Answers3

67

Use zip() and sum():

In [1]: l = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 0)]

In [2]: [sum(x) for x in zip(*l)]
Out[2]: [25, 20]

or:

In [4]: map(sum, zip(*l))
Out[4]: [25, 20]

timeit results:

In [16]: l = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 0)]*1000

In [17]: %timeit [sum(x) for x in zip(*l)]
1000 loops, best of 3: 1.46 ms per loop

In [18]: %timeit [sum(x) for x in izip(*l)]       #prefer itertools.izip
1000 loops, best of 3: 1.28 ms per loop

In [19]: %timeit map(sum, zip(*l))
100 loops, best of 3: 1.48 ms per loop

In [20]: %timeit map(sum, izip(*l))                #prefer itertools.izip
1000 loops, best of 3: 1.29 ms per loop
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • O_O can't believe how simple that was, how could I have forgot about `zip`? thanks. Which is more efficient? the `map` or `list-comprehension` method? – Inbar Rose Jan 06 '13 at 09:34
  • 2
    `map` sometimes outperforms `list comprehension` when used with built-in functions. – Ashwini Chaudhary Jan 06 '13 at 09:36
  • 2
    Out of interest, what does the asterisk mean when you go `zip(*l)`? – nick_w Jan 10 '13 at 08:04
  • 3
    @nick_w for `zip()` when used with * acts like unzipping a list. http://docs.python.org/2/library/functions.html#zip – Ashwini Chaudhary Jan 10 '13 at 08:12
  • This can be made slightly faster by using 'map' instread of a loop. As follows: map(sum,zip(*res)) – jhrf Mar 18 '14 at 15:28
  • @jhrf Perhaps you should look at the answer one more time. – Ashwini Chaudhary Mar 18 '14 at 18:10
  • @Aशwiniचhaudhary OPPS! Sorry for not reading the answer completely. I am surprised, however, that map fails to beat an inline for loop even using izip (even if the difference is slight). My understanding was that inline for-loops were slower than map. Am I wrong about this? Pardon my silly comment! – jhrf Mar 19 '14 at 15:44
  • Just want to mention that the timing results is for Python 2, since in Python 3 `zip` is an iterator this the `itertools.izip` doesn't exist. – Ignacio Vergara Kausel Jul 04 '19 at 12:06
4

Without using zip

sum(e[0] for e in l), sum(e[1] for e in l)
cipilo
  • 81
  • 3
3

I want to add something to the given answer:

If I have an array of dict e.g.

l = [{'quantity': 10, 'price': 5},{'quantity': 6, 'price': 15},{'quantity': 2, 'price': 3},{'quantity': 100, 'price': 2}]

and i want to obtain two (or more) sums of calculated quantity over the values e.g. sum of quantities and of price*quantity

I can do:

(total_quantity, total_price) = (
sum(x) for x in zip(*((item['quantity'],
                       item['price'] * item['quantity'])
                      for item in l)))

Instead of:

total_quantity = 0
total_price = 0
for item in l:
     total_quantity += item['quantity']
     total_price += item['price'] * item['quantity']

Maybe the first solution is less readable, but is more "pythonesque" :)

Alessandro Ruffolo
  • 1,575
  • 1
  • 16
  • 34
  • 1
    What does that add to Ashwini's answer? The question is not about a list of dicts – Tim Sep 24 '15 at 16:23
  • 1
    you're right, but it adds something about using sum and zip for complex operations. I was looking for something like that, I've found this answer and I used it for my own problem, which was about dicts. Thus I thought it would be nice to share my solution with somebody else who could have my same issue. – Alessandro Ruffolo Sep 24 '15 at 16:27