python's sum() and non-integer values

前端 未结 6 1602
耶瑟儿~
耶瑟儿~ 2020-12-01 18:04

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)
               


        
相关标签:
6条回答
  • 2020-12-01 18:32

    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)
    
    0 讨论(0)
  • 2020-12-01 18:34

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

    0 讨论(0)
  • 2020-12-01 18:36

    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
    
    0 讨论(0)
  • 2020-12-01 18:37

    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__.

    0 讨论(0)
  • 2020-12-01 18:37

    sum() (without integer hack) solution seems the cleanest; because sum() starts with the zero, handle this case (from http://www.marinamele.com/2014/04/modifying-add-method-of-python-class.html):

    def __radd__(self, other):
        if other == 0:
            return self
        else:
            return other.__add__(self)
    
    0 讨论(0)
  • 2020-12-01 18:39

    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)
    
    0 讨论(0)
提交回复
热议问题