Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sum each value in a list of tuples

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?

like image 241
Inbar Rose Avatar asked Jan 06 '13 09:01

Inbar Rose


People also ask

How do you sum a list of tuples?

To find a sum of the tuple in Python, use the sum() method. Define a tuple with number values and pass the tuple as a parameter to the sum() function; in return, you will get the sum of tuple items.

How do you sum a tuple element in Python?

Using sum() to get the total in a tuple The built-in sum() function in Python is used to return the sum of an iterable. To get the sum total of a tuple of numbers, you can pass the tuple as an argument to the sum() function.


3 Answers

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
like image 105
Ashwini Chaudhary Avatar answered Oct 05 '22 12:10

Ashwini Chaudhary


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" :)

like image 21
Alessandro Ruffolo Avatar answered Oct 05 '22 11:10

Alessandro Ruffolo


Without using zip

sum(e[0] for e in l), sum(e[1] for e in l)
like image 29
cipilo Avatar answered Oct 05 '22 10:10

cipilo