Python element-wise tuple operations like sum

PythonTuples

Python Problem Overview


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?

Python Solutions


Solution 1 - Python

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

Solution 2 - Python

Using all built-ins..

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

Solution 3 - Python

This solution doesn't require an import:

tuple(map(lambda x, y: x + y, tuple1, tuple2))

Solution 4 - Python

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

Solution 5 - Python

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.

Solution 6 - Python

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))

Solution 7 - Python

simple solution without class definition that returns tuple

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

Solution 8 - Python

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

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

Solution 9 - Python

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)

Solution 10 - Python

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))

Solution 11 - Python

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)

Solution 12 - Python

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)

Solution 13 - Python

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.

Solution 14 - Python

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))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRodrigoView Question on Stackoverflow
Solution 1 - PythonironfroggyView Answer on Stackoverflow
Solution 2 - PythonKenan BanksView Answer on Stackoverflow
Solution 3 - PythonBoaz ShvartzmanView Answer on Stackoverflow
Solution 4 - PythonMikeView Answer on Stackoverflow
Solution 5 - PythonDanaView Answer on Stackoverflow
Solution 6 - PythonJaehyun YeomView Answer on Stackoverflow
Solution 7 - PythonDemonEyeView Answer on Stackoverflow
Solution 8 - PythonMikeView Answer on Stackoverflow
Solution 9 - PythonLetsPlayYahtzeeView Answer on Stackoverflow
Solution 10 - PythonDougView Answer on Stackoverflow
Solution 11 - Pythonuser2012588View Answer on Stackoverflow
Solution 12 - PythonHuguesView Answer on Stackoverflow
Solution 13 - PythonKonchogView Answer on Stackoverflow
Solution 14 - PythonytutowView Answer on Stackoverflow