Reputation: 10689
I am hoping someone can help me with a problem I'm stuck with. I have a large number of tuples (>500) that look like this:
(2,1,3,6)
(1,2,5,5)
(3,0,1,6)
(10,1,1,4)
(0,3,3,0)
A snippet of my code reads:
sum1 = (A,B,C,D) # creates a tuple of sums of (A,B,C,D)
mysum = map(sum, zip(A, B, C, D))
print(mysum)
I realize the above code is not correct. I am trying to find a way to add all the values A together, all the values of B together, all the values of C together, and all the values of D together using the zip function. For example, I would like to print something that looks like this:
Asum = 16
Bsum = 7
Csum = 13
Dsum = 21
Can anyone help please? Thanks very much for your time.
Upvotes: 8
Views: 48594
Reputation: 91094
>>> zip((1,2,3),(10,20,30),(100,200,300))
[(1, 10, 100), (2, 20, 200), (3, 30, 300)]
>>> [sum(x) for x in zip((1,2,3),(10,20,30),(100,200,300))]
[111, 222, 333]
To do this with an arbitrarily large set of tuples:
>>> myTuples = [(1,2,3), (10,20,30), (100,200,300)]
>>> [sum(x) for x in zip(*myTuples)]
[111, 222, 333]
sidenote: in python3, note that zip returns a lazy iterable, which you can always explicitly turn into a list like any other kind of iterable: list(zip(...))
(thanks to Seganku for catching mistake in examples in an edit which was thrice rejected by other editors)
Upvotes: 17
Reputation: 7056
It your sets are all the same size and you are working in C Python, you should consider using numpy. You can do this in numpy like so:
In [5]: sets = ((2,1,3,6),
...: (1,2,5,5),
...: (3,0,1,6),
...: (10,1,1,4),
...: (0,3,3,0) )*100
In [6]: import numpy as np
In [7]: A = np.array(sets)
In [8]: np.sum(A, axis=0)
Out[8]: array([1600, 700, 1300, 2100])
Numpy converts your values to an array and works with them efficiently using optimized LAPACK functions.
To compare performance, I profiled under two sets of assumptions. In the first, I assume that your data is stored such that importing into a Numpy array is efficient, so I didn't include the time necessary to convert sets to an array. I compared the performance of np.sum to [sum(x) for x in zip(*sets)]. Here are the timeit results for each case:
Excluding numpy Array Conversion: 0.0735958760122
Including numpy Array Conversion: 17.1435046214
Plain old zip: 0.660146750495
The conclusion is that numpy is faster if your input data can easily be imported with numpy.
Upvotes: 2
Reputation: 38116
tuples = [(2,1,3,6), (1,2,5,5), (3,0,1,6), (10,1,1,4), (0,3,3,0)]
s = [sum(tup) for tup in zip(*tuples)]
Asum, Bsum, Csum, Dsum = s
Upvotes: 0
Reputation: 816404
If you have all that tuples in a list, then you could use reduce()
:
>>> list(reduce(lambda x,y: (i+j for i,j in zip(x,y)), tuples, [0]*4))
[16, 7, 13, 21]
Upvotes: 0
Reputation:
map(sum, zip(a, b, c, d, e))
The first call, to zip
, inverts the lists - makes a list of all first elements, all second elements, etc.
The second call, map
, calls its first argument sum
on its second argument, those lists, returning a list of the results of sum
- which happens to be the sums.
Upvotes: 4