Velvet Star Monitor

Standout celebrity highlights with iconic style.

general

Python element-wise tuple operations like sum

Writer Olivia Zamora

Is there anyway to get tuple operations in Python to work like this:

>>> a = (1,2,3)
>>> b = (3,2,1)
>>> a + b
(4,4,4)

instead of:

>>> a = (1,2,3)
>>> b = (3,2,1)
>>> a + b
(1,2,3,3,2,1)

I know it works like that because the __add__ and __mul__ methods are defined to work like that. So the only way would be to redefine them?

14 Answers

import operator
tuple(map(operator.add, a, b))
8

Using all built-ins..

tuple(map(sum, zip(a, b)))
4

This solution doesn't require an import:

tuple(map(lambda x, y: x + y, tuple1, tuple2))
1
from numpy import array
a = array( [1,2,3] )
b = array( [3,2,1] )
print a + b

gives array([4,4,4]).

See

1

Sort of combined the first two answers, with a tweak to ironfroggy's code so that it returns a tuple:

import operator
class stuple(tuple): def __add__(self, other): return self.__class__(map(operator.add, self, other)) # obviously leaving out checking lengths
>>> a = stuple([1,2,3])
>>> b = stuple([3,2,1])
>>> a + b
(4, 4, 4)

Note: using self.__class__ instead of stuple to ease subclassing.

0

Generator comprehension could be used instead of map. Built-in map function is not obsolete but it's less readable for most people than list/generator/dict comprehension, so I'd recommend not to use map function in general.

tuple(p+q for p, q in zip(a, b))

simple solution without class definition that returns tuple

import operator
tuple(map(operator.add,a,b))

All generator solution. Not sure on performance (itertools is fast, though)

import itertools
tuple(x+y for x, y in itertools.izip(a,b))

even simpler and without using map, you can do that

>>> tuple(sum(i) for i in zip((1, 2, 3), (3, 2, 1)))
(4, 4, 4)

Yes. But you can't redefine built-in types. You have to subclass them:

class MyTuple(tuple): def __add__(self, other): if len(self) != len(other): raise ValueError("tuple lengths don't match") return MyTuple(x + y for (x, y) in zip(self, other))
1

I currently subclass the "tuple" class to overload +,- and *. I find it makes the code beautiful and writing the code easier.

class tupleN(tuple): def __add__(self, other): if len(self) != len(other): return NotImplemented else: return tupleN(x+y for x,y in zip(self,other)) def __sub__(self, other): if len(self) != len(other): return NotImplemented else: return tupleN(x-y for x,y in zip(self,other)) def __mul__(self, other): if len(self) != len(other): return NotImplemented else: return tupleN(x*y for x,y in zip(self,other))
t1 = tupleN((1,3,3))
t2 = tupleN((1,3,4))
print(t1 + t2, t1 - t2, t1 * t2, t1 + t1 - t1 - t1)
(2, 6, 7) (0, 0, -1) (1, 9, 12) (0, 0, 0)

Here is another handy solution if you are already using numpy. It is compact and the addition operation can be replaced by any numpy expression.

import numpy as np
tuple(np.array(a) + b)

I keep coming back to this question, and I don't particularly like any of the answers as they are all answering the question for the general case, and I'm normally looking for the answer to a special case: I'm normally using a fixed tuple count, e.g. for n-dimensions.

 # eg adding a dx/dy to an xy point. # if I have a point xy and another point dxdy x, y = xy dx, dy = dxdy return x+dx, y+dy

while I normally shudder at unnecessary variables, the reason why I am unpacking a tuple is normally because I am working on the elements as individuals, and that is what is happening with tuple addition as requested above.

In case someone need to average a list of tuples:

import operator
from functools import reduce
tuple(reduce(lambda x, y: tuple(map(operator.add, x, y)),list_of_tuples))

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy