将空元组作为sum()函数的第二个参数

4

请注意,不要使用“that”来展平元组,因为复杂性非常糟糕。 - Jean-François Fabre
3个回答

5
第二个参数是起始值,它不是要开始计算的索引,而是要开始求和的值。
例如: sum([1,2,3], 0) 等同于 0 + 1 + 2 + 3 sum([1,2,3], 6) 等同于 6 + 1 + 2 + 3 sum(((1,2), ('a','b')), ()) 等同于 () + (1,2) + ('a','b') 由于默认情况下,如果没有指定起始值,则起始值为0,因此您将得到: 0 + (1,2) + ('a','b') 这将导致 TypeError: unsupported operand type(s) for +: 'int' and 'tuple'

3
简短回答:因为+(由sum使用)可以被重新定义,如果您没有提供数字值的可迭代对象,则需要提供一个适当类型的起始值。

第二个参数用作总和中的“起点”。它基本上是求和的起点:

>>> sum([1,2,3])
6
>>> sum([1,2,3], 0)
6
>>> sum([1,2,3], 2)
8

它的默认值为0,如果您想要求和的序列不是数字,则会出现问题,因为 0 +(1,2)未定义。相反,您需要提供一个可以添加到序列元素的值;虽然0是数字加法的标识,但 sum 不知道元组连接的等效值是什么,您必须直接提供它。

>>> sum(((1,2), ('a', 'b')))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'tuple'
>>> sum(((1,2), ('a', 'b')), ())
(1, 2, 'a', 'b')
>>> sum(((1,2), ('a', 'b')), (True,))
(True, 1, 2, 'a', 'b')

1

这个答案解释了默认参数,但是sum不应该被用来展开元组或列表,因为会产生二次方的影响。请参见列表上的sum是否可以更快

所以:

为什么sum()的第二个参数可以是一个空元组?难道不应该是一个数字吗?

是的,它应该是一个数字,如果你想保持高效,sum应该始终应用于数字元素。这个默认参数在这里提供了一个替代方案,而不是00.0

每次遇到要求和的项时,它不执行原地加法,而是类似于(内部):

result = result + new_item

这会导致在每次迭代时都需要复制旧内容,从而使listtuple的复杂度为O(n**2)。因此不要这样做(请注意,对于str类型,它是明确被阻止的)。
相反,使用双层扁平化表达式并创建一个tuple
tmp=((1,2), ('a','b'))

result = tuple(x for st in tmp for x in st)

如果您的元组包含大量元素,您将看到速度差异。

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