suma () de python y valores no enteros
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
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)