内置函数sum与sum(list,[])有什么关系?

C_Y*_*C_Y 21 python

当我想展开一个列表时,我找到了如下方式:

>>> a = [[1, 2], [3, 4], [5, 6]]
>>> a
[[1, 2], [3, 4], [5, 6]]
>>> sum(a, [])
[1, 2, 3, 4, 5, 6]
Run Code Online (Sandbox Code Playgroud)

我不知道这些行发生了什么,文档说明:

sum(iterable[, start])

资金start和一个项目iterable从左到右,并返回总.start默认为0.iterable的项通常是数字,并且start不允许该值为字符串.

对于某些用例,有很好的替代方案sum().连接字符串序列的首选快速方法是调用 ''.join(sequence).要以扩展精度添加浮点值,请参阅math.fsum().要连接一系列迭代,请考虑使用itertools.chain().

版本2.3中的新功能.

难道你不认为开始应该是一个数字?为什么[]可以写在这里?

(sum(a, []))
Run Code Online (Sandbox Code Playgroud)

jon*_*rpe 28

难道你不认为开始应该是一个数字?

start 默认情况下是一个数字; 0,根据您引用的文档.因此当你这样做时:

sum((1, 2))
Run Code Online (Sandbox Code Playgroud)

它被评估为0 + 1 + 2等于3并且每个人都很开心.如果你想从不同的号码开始,你可以提供:

>>> sum((1, 2), 3)
6
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.


但是,您可以使用其他内容+,例如列表:

>>> ['foo'] + ['bar']
['foo', 'bar']
Run Code Online (Sandbox Code Playgroud)

但是,如果您尝试使用sum此功能,则会得到相同的结果TypeError:

>>> sum((['foo'], ['bar']))

Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    sum((['foo'], ['bar']))
TypeError: unsupported operand type(s) for +: 'int' and 'list'
Run Code Online (Sandbox Code Playgroud)

因为它现在正在做0 + ['foo'] + ['bar'].

为了解决这个问题,你可以提供自己的start作为[],所以它成为[] + ['foo'] + ['bar']所有再好.所以回答:

为什么[]可以写在这里?

因为虽然start默认为一个数字,它不具备成为一个; 其他东西也可以添加,这对于你正在做的事情来说非常方便.

  • 但请注意 - 这需要二次时间!由于`sum`总是使用`+`,如果你尝试将它用于列表连接,它将为每个中间串联构建一个新的中间列表,它需要两次复制. (5认同)
  • sum实际上被编码为拒绝字符串。它给出错误`TypeError:sum()无法求和字符串[改为使用''.join(seq)]`` (2认同)

Kas*_*mvd 6

实际上,该sum函数使用iterable的所有项调用每次迭代中的sum属性__add__.

例如 :

>>> [].__add__([2,3])
[2, 3]
#OR
>>> [] + [1,2,3]
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,结果将是输入列表的连接列表.实际上,在算法透视图中,它执行以下过程:

>>> a = [[1, 2], [3, 4], [5, 6]]
>>> start = []
>>> for i in a:
...     start += i
... 
>>> start
[1, 2, 3, 4, 5, 6]
Run Code Online (Sandbox Code Playgroud)

并不是说你可以start在具有sum属性的每个对象序列上调用该函数.但请注意,因为它的默认__add__参数是,start如果你的对象不是整数,它将引发一个0.在这种情况下,您需要指定适当TypeError的功能.

>>> class newObj(object):
...    def  __init__(self,val):
...         self.val = val
...    def __add__(self,item):
...        return '{}_____{}'.format(self.val,item)
... 
>>> 
>>> start=newObj('new_obj')
>>> 
>>> start
<__main__.newObj object at 0x7f75f9241c50>
>>> 
>>> start + 5
'new_obj_____5'
>>> 
>>> 
>>> sum(['1','2','3'],start)
'new_obj_____123'
Run Code Online (Sandbox Code Playgroud)