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?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
import operator tuple(map(operator.add, a, b))
Method 2
Using all built-ins..
tuple(map(sum, zip(a, b)))
Method 3
This solution doesn’t require an import:
tuple(map(lambda x, y: x + y, tuple1, tuple2))
Method 4
from numpy import array a = array( [1,2,3] ) b = array( [3,2,1] ) print a + b
gives array([4,4,4]).
See http://www.scipy.org/Tentative_NumPy_Tutorial
Method 5
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.
Method 6
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))
Method 7
simple solution without class definition that returns tuple
import operator tuple(map(operator.add,a,b))
Method 8
All generator solution. Not sure on performance (itertools is fast, though)
import itertools tuple(x+y for x, y in itertools.izip(a,b))
Method 9
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)
Method 10
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))
Method 11
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)
Method 12
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)
Method 13
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.
Method 14
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))
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0