Pregunta

¿Existe una manera simple y rápida de usar sum () con valores no enteros?

Entonces puedo usarlo así:

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

Intenté anular __add__ y __int__ etc., pero todavía no he encontrado una solución

EDIT:

La solución es implementar:

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

como Will sugirió en su publicación. Pero como siempre, todos los caminos conducen a Roma, pero creo que esta es la mejor solución ya que no necesito __add__ en mi clase

¿Fue útil?

Solución

Es un poco complicado: la función sum () toma el inicio y la agrega a la siguiente, etc.

Debe implementar el método __radd__ :

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)

Otros consejos

También es posible que necesite implementar la función __radd__ , que representa " reverse add " y se invoca cuando los argumentos no se pueden resolver en el " reenviar " dirección. Por ejemplo, x + y se evalúa como x .__ add __ (y) si es posible, pero si eso no existe, Python intenta y .__ radd __ (x ) .

Dado que la función sum () comienza con el entero 0 , lo primero que hace es intentar evaluar:

0 + Foo(3)

que requerirá que implemente Foo .__ radd__ .

Prueba:

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

sum () funciona probablemente más rápido, pero está especializado solo para números incorporados. Por supuesto, aún debe proporcionar un método para agregar sus objetos Foo (). Así ejemplo completo:

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

O si no quieres importar nada,

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

Otra pequeña ventaja es que no tiene que declarar necesariamente un método __add__ como parte de sus objetos Foo, si esta es la única circunstancia en la que desea realizar la suma . (Pero probablemente no estaría de más definir __add__ para una flexibilidad futura).

Intente utilizar el método __int__ y luego asigne cada elemento de su lista a la función int para obtener los valores:

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)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top