今天,我自动写了一些这样的事情:
class Foo():
def __init__(self, x):
self.x = x
s = [Foo(1), Foo(2), Foo(3)]
sum_x = sum(s, key = lambda foo: foo.x)
得到了这个:
TypeError:sum()不带关键字参数
sum()
没有key
arg有什么特殊原因吗?
答案 0 :(得分:6)
因为您可以改为编写@Document
。如果您尝试使用其中一个确实采用sum(foo.x for foo in s)
参数(key
,sorted
,min
等等的函数执行此操作,则该函数最终会返回键(而不是原始项),并且按键排序时获取原始项是非常棘手的,以至于Python通过关键字参数为您提供了内置方法。
因此:max
没有特殊理由不接受sum
;相反,那些其他功能有特殊的原因,为什么他们做采取key
。 key
是例外,而不是规则。
答案 1 :(得分:2)
没有key
参数,因为sum()
未返回原始元素(例如sorted()
,min()
和max()
)。相反,它只是对输入进行求和。
如果min()
没有采用key
参数,则无法根据属性返回最小Foo()
个对象;它只能返回该属性的值。但是sum()
不起作用,它不需要保留原始对象。
您可以轻松转换生成器表达式中的输入:
sum(item.x for item in s)
答案 2 :(得分:1)
虽然没有key
参数,但好消息是可以使用sum
与您的Foo
对象!其他人已经指出了最简单的方法
这样做
sum(item.x for item in s)
但是,也可以在不理解的情况下使用它。
为了使总和发挥作用,基本的补充需要先行。
In [2]: class Foo:
...: def __init__(self, x):
...: self.x = x
...:
In [3]: Foo(3) + Foo(5)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-f0e9c3a4abb9> in <module>()
----> 1 Foo(3) + Foo(5)
TypeError: unsupported operand type(s) for +: 'Foo' and 'Foo'
我们可以通过定义__add__
方法来启用添加。
In [4]: class Foo:
...: def __init__(self, x):
...: self.x = x
...: def __add__(self, other):
...: return Foo(self.x + other.x)
...:
In [5]: Foo(3) + Foo(5)
Out[5]: <__main__.Foo at 0x102bdc2e8>
明确说明它有效
In [6]: result = Foo(3) + Foo(5)
In [7]: result.x
Out[7]: 8
但这并不能解决所有问题。
In [8]: sum([Foo(3), Foo(5)])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-70968119f3ba> in <module>()
----> 1 sum([Foo(3), Foo(5)])
TypeError: unsupported operand type(s) for +: 'int' and 'Foo'
我们没有尝试添加int
,但sum
函数认为我们做了。是什么给了什么?
sum
功能使用ipython检查sum
函数,你可以看到它包含一个
可选的start
参数
In [1]: sum??
Docstring:
sum(iterable[, start]) -> value
Return the sum of an iterable of numbers (NOT strings) plus the value
of parameter 'start' (which defaults to 0). When the iterable is
empty, return start.
Type: builtin_function_or_method
因此,sum(s)
与sum(s, 0)
相同,就是这个开始
导致错误的值。我们所要做的就是替换起始值
使用等效的Foo
对象
In [9]: sum([Foo(3), Foo(5)], Foo(0))
Out[9]: <__main__.Foo at 0x102bdc9e8>
In [10]: result = sum([Foo(3), Foo(5)], Foo(0))
In [11]: result.x
Out[11]: 8
这也适用于其他一些类型
In [12]: sum([[1,2,3], [4,5,6]], [])
Out[12]: [1, 2, 3, 4, 5, 6]
但不是全部
In [13]: sum(["abc", "def"], "")
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-13-452a33de0457> in <module>()
----> 1 sum(["abc", "def"], "")
TypeError: sum() can't sum strings [use ''.join(seq) instead]