Python element-wise tuple operations like sum
import operator
tuple(map(operator.add, a, b))
Adding two tuples elementwise
Zip them, then sum each tuple.
[sum(x) for x in zip(a,b)]
EDIT : Here's a better, albeit more complex version that allows for weighting.from itertools import starmap, islice, izip
a = [1, 2, 3]
b = [3, 4, 5]
w = [0.5, 1.5] # weights => a*0.5 + b*1.5
products = [m for m in starmap(lambda i,j:i*j, [y for x in zip(a,b) for y in zip(x,w)])]
sums = [sum(x) for x in izip(*[islice(products, i, None, 2) for i in range(2)])]
print sums # should be [5.0, 7.0, 9.0]
sum each value in a list of tuples
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
Elementwise operations over tuples in Python
map function
>>> a = (1, 2, 4)
>>> b = (1.1, 2.1, 4.1)
>>> map(lambda a,b: 100*abs(a-b)/a < 3, a, b)
[False, False, True]
EDITof course instead of map, you can use list comprehensions, like BrenBarn did http://docs.python.org/tutorial/datastructures.html#nested-list-comprehensions
EDIT 2 zip removed, thanks for DSM to point it out that zip is not needed
How can I pairwise sum two equal-length tuples
tuple(map(lambda (x, y): x + y, zip((0,-1,7), (3,4,-7))))
If you prefer to avoid map
and lambda
then you can do:tuple(x + y for x,y in zip((0,-1,7), (3,4,-7)))
EDIT: As one of the answers pointed out, you can use sum instead of explicitly splitting the tuples returned by zip
. Therefore you can rewrite the above code sample as shown below: tuple(sum(t) for t in zip((0,-1,7), (3,4,-7)))
Reference: zip
, map
, sum
. Element-wise addition of 2 lists?
Use map
with operator.add
:
>>> from operator import add
>>> list( map(add, list1, list2) )
[5, 7, 9]
or zip
with a list comprehension:>>> [sum(x) for x in zip(list1, list2)]
[5, 7, 9]
Timing comparisons:
>>> list2 = [4, 5, 6]*10**5
>>> list1 = [1, 2, 3]*10**5
>>> %timeit from operator import add;map(add, list1, list2)
10 loops, best of 3: 44.6 ms per loop
>>> %timeit from itertools import izip; [a + b for a, b in izip(list1, list2)]
10 loops, best of 3: 71 ms per loop
>>> %timeit [a + b for a, b in zip(list1, list2)]
10 loops, best of 3: 112 ms per loop
>>> %timeit from itertools import izip;[sum(x) for x in izip(list1, list2)]
1 loops, best of 3: 139 ms per loop
>>> %timeit [sum(x) for x in zip(list1, list2)]
1 loops, best of 3: 177 ms per loop
Summing up two lists of tuples on a condition
An obvious solution is to create a result dictionary, then add all values from the first list and then all values from the second list:
from collections import defaultdict
result = defaultdict(int)
for key, value in list1:
result[key] += value
for key, value in list2:
result[key] += value
# convert dictionary-like to list of tuples if you want
result = list(result.items())
Using a dictionary as result spares you from doing a linear search to find the key to which to add a value (leading to an overall quadratic complexity), and a defaultdict
in particular spares you from doingif key not in result:
result[key] = 0
to initialize the result before adding the first value.You can generalize this to any number of input lists by using itertools.chain
:
from collections import defaultdict
from itertools import chain
input_lists = [list1, list2]
result = defaultdict(int)
for key, value in chain.from_iterable(input_lists):
result[key] += value
Visually there is now only one for
loop but under the hoods it is doing the same. How to add with tuples
Do you want to do element-wise addition, or to append the tuples? By default python does
(1,2)+(3,4) = (1,2,3,4)
You could define your own as:def myadd(x,y):
z = []
for i in range(len(x)):
z.append(x[i]+y[i])
return tuple(z)
Also, as @delnan's comment makes it clear, this is better written asdef myadd(xs,ys):
return tuple(x + y for x, y in izip(xs, ys))
or even more functionally:myadd = lambda xs,ys: tuple(x + y for x, y in izip(xs, ys))
Then do if( b < a) return myadd((1,0),foo(a-b,b))
Related Topics
How to Create Module-Wide Variables in Python
Pycharm Error: 'No Module' When Trying to Import Own Module (Python Script)
How to Get the Version Defined in Setup.Py (Setuptools) in My Package
Broken References in Virtualenvs
How to Multiply Individual Elements of a List with a Number
Crontab Not Executing a Python Script
How to Get Tweets Older Than a Week (Using Tweepy or Other Python Libraries)
Why Isn't .Ico File Defined When Setting Window's Icon
"Overflowerror: Python Int Too Large to Convert to C Long" on Windows But Not MAC
Loading JSONl File as JSON Objects
Wrapping Long Y Labels in Matplotlib Tight Layout Using Setp
Counting Cars Opencv + Python Issue
Method Not Allowed Flask Error 405
What Is the Official "Preferred" Way to Install Pip and Virtualenv Systemwide
How to Handle Exceptions in a List Comprehensions
Tuple Unpacking Order Changes Values Assigned
Networkx - Change Color/Width According to Edge Attributes - Inconsistent Result