应用于字典的内置函数sum()返回其键的总和:
sum({1:0,2:10})=3
我想创建一个字典的子类,比如SubDict,然后重写一些函数来返回它的值的总和。
sum(SubDict((1,0),(2,10))=10
要实现此功能,我需要重写哪个函数?
附注:这是一个一般性的问题,如何对一个类实现内置的sum()函数,而不仅仅是在这个特定的情况下。
发布于 2013-08-09 05:35:32
你可以这样做:
In [1]: sum({1:0,2:10}.values())
Out[1]: 10
如果您想实现一个子类,它的sum
将是值的和,只需覆盖__iter__
方法:
In [21]: class MyDict(dict):
....: def __iter__(self):
....: for value in self.values():
....: yield value
....:
In [22]: d = MyDict({1:0,2:10})
In [23]: sum(d)
Out[23]: 10
但是你不能这样做:
for key in d:
print d[key]
因为__iter__
函数将返回值...您必须始终使用keys()
函数:
for key in d.keys():
print d[key]
更好的解决方案是添加一个sum
方法:
In [24]: class MyDict(dict):
....: def sum(self):
....: return sum(self.values())
....:
In [25]: d = MyDict({1:0,2:10})
In [26]: d.sum()
Out[26]: 10
发布于 2013-08-09 05:34:17
sum
的有效实现方式如下:
def sum(sequence, start=0):
for value in sequence:
start = start + value
return start
因此,您不能直接使用…覆盖sum
但是,如果您可以覆盖for value in …
对序列的工作方式,*或+
对您的值的工作方式,这将自动影响sum
。当然,其中任何一个都会有副作用--您将影响序列的任何迭代,或者值的任何添加,而不仅仅是sum
中的值。
要覆盖迭代,您需要提供一个返回适当迭代器的__iter__
方法。要覆盖加法,您需要提供一个__add__
方法。
但说真的,你为什么要尝试“覆盖sum”呢?为什么不直接写一个新的函数来做你想做的事情呢?你可以添加代码,使你的类型特殊,否则就会回到内置的sum
。如果你想让它更“开放”,你可以使用PEP 443单分派来使注册新的特殊类型变得容易。我想这才是你真正想要的。
*正如agf在注释中指出的那样,尽管参数名为sequence
,但它实际上需要任何可迭代的参数。这是一件好事,因为字典不是序列…
https://stackoverflow.com/questions/18136507
复制相似问题