将列表中的所有元素相加

8
我想要将一个类的实例列表组合起来,该类定义了__add__方法。
例如,我有一个类实例列表L=[A,B,C,D],我希望它们相加得到E = A+B+C+D,但是可以推广为使用sum(L)代替+语法。
应该使用什么函数来实现?__add__方法是否足够,还是需要定义一个不同的类方法(例如__iadd__)才能完成这个任务?
(如果发现这是重复问题,我应该如何提问?)

3
__iadd__ 是标准运算符方法之一。 - Taymon
@Taymon 对不起,是我的错误。我已经删除了有问题的评论。 - Adam Mihalcin
3个回答

5
import operator
reduce(operator.add, L)

啊,不小心按到删除键了。[甚至还点了“是”的确认。] 虽然sum(L)不能用,但是sum(L, the_zero)可以—— __add__ 方法被调用了,只是从默认值0开始罢了。 - DSM
请注意,在最近的版本中,sum不允许在起始元素中使用字符串,并且所有归结为反复调用+的解决方案对于列表、元组等也是低效的——对于连接字符串,强烈推荐使用str.join - user395760
好答案;+1 但 unutbu 更直接地回答了问题(需要为 sum 定义 __radd__ 才能工作)。 - keflavich

4

sum 可能希望将数值添加到你的类的实例中。定义 __radd__,这样例如 int + Foo(1) 就会被定义:

class Foo(object):
    def __init__(self, val):
        self.val = val
    def __add__(self, other):
        return self.val + other.val
    def __radd__(self, other):
        return other + self.val

A = Foo(1)
B = Foo(2)
L = [A,B]
print(A+B)
# 3

print(sum(L))
# 3

3

请忽略我之前的回答,那是错误的。

reduce函数允许您将任何二元函数或方法应用于序列的所有元素。因此,您可以编写以下代码:

reduce(YourClass.__add__, sequence)

如果序列中不是所有对象都是同一类的实例,则使用以下方法:

import operator
reduce(operator.add, sequence)

或者是这样:
reduce(lambda x, y: x + y, sequence)

将来您可能希望编辑您的答案,而不是删除它并创建一个新的。 - Zach Kelling
通常我会这样做,但由于旧答案是100%错误的,我认为应该将其删除。 - Taymon
你可以完全更改它,然后 :) - Zach Kelling
我也遇到了同样的问题,后来发现使用 reduce 函数完美解决了。 - astrochun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接