Reputation: 2795
I was just wondering if there was an especially pythonic way of adding two tuples elementwise?
So far (a and b are tuples), I have
map(sum, zip(a, b))
My expected output would be:
(a[0] + b[0], a[1] + b[1], ...)
And a possible weighing would be to give a 0.5 weight and b 0.5 weight, or so on. (I'm trying to take a weighted average).
Which works fine, but say I wanted to add a weighting, I'm not quite sure how I would do that.
Thanks
Upvotes: 28
Views: 52492
Reputation: 11588
If your tuples contain str
objects:
list(map(''.join, zip('abc', '123')))
# Returns ['a1', 'b2', 'c3']
Upvotes: 0
Reputation: 22492
If you do not mind the dependency, you can use numpy for elementwise operations on arrays
>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> b = np.array([3, 4, 5])
>>> a + b
array([4, 6, 8])
Upvotes: 9
Reputation: 20757
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]
Upvotes: 29
Reputation: 50200
Take the formula for the weighted sum of one pair of coordinates, and form a tuple with an iterator over each pair (note the two variables after the for
):
tuple(0.5*an + 0.5*bn for an, bn in zip(a, b))
This keeps it simple and readable as a one-liner. Of course if your "weighted sum" is a complicated function, you'd define it as a separate function first.
Upvotes: 3
Reputation: 387745
>>> a = (1, 2, 3)
>>> b = (4, 5, 6)
>>> def averageWeightedSum(args):
return sum(args) / len(args)
>>> tuple(map(averageWeightedSum, zip(a, b)))
(2.5, 3.5, 4.5)
An alternative would be to apply the weights first. This would also allow you to have different weights:
>>> from operator import mul
>>> weights = (0.3, 0.7)
>>> tuple(sum(map(mul, x, weights)) for x in zip(a, b))
(3.0999999999999996, 4.1, 5.1)
>>> weights = (0.5, 0.5)
>>> tuple(sum(map(mul, x, weights)) for x in zip(a, b))
(2.5, 3.5, 4.5)
Upvotes: 6