Question

Is there a simple and quick way to use sum() with non-integer values?

So I can use it like this:

class Foo(object):
    def __init__(self,bar)
        self.bar=bar

mylist=[Foo(3),Foo(34),Foo(63),200]
result=sum(mylist) # result should be 300

I tried overriding __add__ and __int__ etc, but I don't have found a solution yet

EDIT:

The solution is to implement:

 def __radd__(self, other):
    return other + self.bar

as Will suggested in his post. But as always, all roads lead to Rome, but I think this is the best solution since I don't need __add__ in my class

Was it helpful?

Solution

Its a bit tricky - the sum() function takes the start and adds it to the next and so on

You need to implement the __radd__ method:

class T:
    def __init__(self,x):
        self.x = x
    def __radd__(self, other):
        return other + self.x

test = (T(1),T(2),T(3),200)
print sum(test)

OTHER TIPS

You may also need to implement the __radd__ function, which represents "reverse add" and is called when the arguments can't be resolved in the "forward" direction. For example, x + y is evaluated as x.__add__(y) if possible, but if that doesn't exist then Python tries y.__radd__(x).

Since the sum() function starts with the integer 0, the first thing it does is try to evaluate:

0 + Foo(3)

which will require that you implement Foo.__radd__.

Try:

import operator
result=reduce(operator.add, mylist)

sum() works probably faster, but it is specialized for builtin numbers only. Of course you still have to provide a method to add your Foo() objects. So full example:

class Foo(object):
    def __init__(self, i): self.i = i
    def __add__(self, other):
        if isinstance(other, int):
            return Foo(self.i + other)
        return Foo(self.i + other.i)
    def __radd__(self, other):
        return self.__add__(other)

import operator
mylist = [Foo(42), Foo(36), Foo(12), 177, Foo(11)]
print reduce(operator.add, mylist).i

Or if you don't want to import anything,

result = reduce((lambda x,y:x+y), mylist)

Another small advantage is that you don't have to necessarily declare an __add__ method as part of your Foo objects, if this happens to be the only circumstance in which you'd want to do addition. (But it probably wouldn't hurt to define __add__ for future flexibility.)

Try using the __int__ method and then mapping each element in your list to the int function to get the values out:

class Foo(object):
    def __init__(self,bar):
        self.bar = bar
    def __int__(self):
        return self.bar

mylist = [Foo(3),Foo(34),Foo(63),200]
result = sum(map(int,mylist))
print(result)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top