是否有一种简单快捷的方法将sum()与非整数值一起使用?
所以我可以这样使用它:
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
我尝试覆盖__add__
和__int__
等,但我还没有找到解决方案
修改
解决方案是实施:
def __radd__(self, other):
return other + self.bar
正如威尔在他的帖子中所建议的那样。但一如既往,所有道路都通往罗马,但我认为这是最好的解决方案,因为我班上不需要__add__
答案 0 :(得分:27)
它有点棘手 - sum()函数接受开始并将其添加到下一个等等
您需要实施__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)
答案 1 :(得分:18)
您可能还需要实现__radd__
函数,该函数表示“反向添加”,并且在无法在“向前”方向上解析参数时调用。例如,如果可能,x + y
将被评估为x.__add__(y)
,但如果不存在,则Python会尝试y.__radd__(x)
。
由于sum()
函数以整数0
开头,它首先要做的是尝试评估:
0 + Foo(3)
这将要求您实施Foo.__radd__
。
答案 2 :(得分:5)
尝试:
import operator
result=reduce(operator.add, mylist)
sum()的工作速度可能更快,但它仅适用于内置数字。当然,您仍然需要提供一种方法来添加您的Foo()对象。如此完整的例子:
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
答案 3 :(得分:5)
或者,如果您不想导入任何内容,
result = reduce((lambda x,y:x+y), mylist)
另一个小优势是,您不必将__add__
方法声明为Foo对象的一部分,如果这恰好是您想要添加的唯一情况。 (但为未来的灵活性定义__add__
可能不会有什么坏处。)
答案 4 :(得分:3)
尝试使用__int__
方法,然后将列表中的每个元素映射到int
函数以获取值:
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)
答案 5 :(得分:-1)
sum()
(无整数限制)解决方案似乎是最干净的;因为sum()
以零开头,请处理这种情况(来自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)