Python 内置函数sum对sum(list,[])有什么作用?

Python 内置函数sum对sum(list,[])有什么作用?,python,Python,当我想要展开一个列表时,我找到了如下方法: >>> a = [[1, 2], [3, 4], [5, 6]] >>> a [[1, 2], [3, 4], [5, 6]] >>> sum(a, []) [1, 2, 3, 4, 5, 6] 我不知道发生了什么,我说: sum(iterable[,start]) 将start和iterable的项目从左到右求和 返回总数开始默认为0。iterable的项目包括: 通常为数字,start值不允许

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

>>> a = [[1, 2], [3, 4], [5, 6]]
>>> a
[[1, 2], [3, 4], [5, 6]]
>>> sum(a, [])
[1, 2, 3, 4, 5, 6]
我不知道发生了什么,我说:

sum(iterable[,start])

start
iterable
的项目从左到右求和 返回总数<代码>开始默认为
0
。iterable的项目包括: 通常为数字,
start
值不允许为字符串

对于某些用例,有很好的替代方法来替代
sum()
。连接字符串序列的首选快速方法是调用
“”。加入(序列)
。使用扩展名添加浮点值的步骤 精度,请参见
math.fsum()
。要连接一系列的可重用项, 考虑使用<代码>迭代器.Car()< <代码> > < /P> 版本2.3中的新功能

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

(sum(a, []))

首先,不要使用
sum
来连接/展平列表,因为它是二次时间,因此与其他方法相比根本没有效率。它实际上使用了一个

sum
函数在每次迭代时调用
start
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu添加
属性,其中包含作为第一个参数传递的iterable的所有项

例如:

>>> [].__add__([2,3])
[2, 3]
#OR
>>> [] + [1,2,3]
[1, 2, 3]
在这种情况下,结果将是输入列表的串联列表。从算法的角度来看,它执行以下操作:

>>> a = [[1, 2], [3, 4], [5, 6]]
>>> start = []
>>> for i in a:
...     start += i
... 
>>> start
[1, 2, 3, 4, 5, 6]
并不是说您可以对具有
\uuuu add\uuuu
属性的任何对象序列调用
sum
函数,而是要注意,由于默认的
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'
>>类newObj(对象):
...    定义初始值(self,val):
...         self.val=val
...    定义添加(自身,项目):
...        返回{}{}。格式(self.val,item)
... 
>>> 
>>>start=newObj('new_obj'))
>>> 
>>>开始
>>> 
>>>开始+5
“新目标5”
>>> 
>>> 
>>>总和(['1'、'2'、'3'],起始)
“新目标123”

start
与作为第一个参数提供的iterable的内容相加
sum
不会将
start
类型限制为整数,以允许各种情况的相加

本质上sum是这样做的:

a = [[1, 2], [3, 4], [5, 6]]
sum(a, number)
number + [1, 2] + [3, 4] + [5, 6]
大致翻译为:

number += every value in the list a
由于列表
a
中的每一个值都是一个列表,因此该列表起作用,前一个总和在展开时如下所示:

a = [[1, 2], [3, 4], [5, 6]]
sum(a, number)
number + [1, 2] + [3, 4] + [5, 6]
因此,如果输入
int
,这将导致不幸的
TypeError
,因为不允许添加
int
列表

1 + [1, 2] == I hope you like TypeErrors
但是,如果您输入一个列表
[]
,它只会将
a
的元素连接在一起,形成我们所知道和喜爱的扁平列表

start
的值默认为
0
an
int
,这主要是因为求和最常见的情况是算术

你不认为开始应该是一个数字吗

start
默认为一个数字<代码>0
,根据您引用的文档。因此,当您这样做时,例如:

sum((1, 2))
它被评估为
0+1+2
,等于
3
,每个人都很高兴。如果您想从不同的号码开始,您可以提供:

>>> sum((1, 2), 3)
6
到目前为止,一切顺利


但是,您还可以在上使用
+
,例如列表:

>>> ['foo'] + ['bar']
['foo', 'bar']
但是,如果您尝试为此使用
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'
总和((['foo'],['bar'])) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 总和((['foo'],['bar'])) TypeError:不支持+:“int”和“list”的操作数类型
因为它现在正在执行
0+['foo']+['bar']

要解决此问题,您可以将自己的
开始
作为
[]
,这样它就变成了
[]+['foo']+['bar']
,一切又好了。因此,我要回答:

为什么
[]
可以写在这里


因为尽管
start
默认为一个数字,但它不必是一;还可以添加其他内容,这对于您当前正在做的事情非常有用。

sum
实际上是编码为拒绝字符串的。它给出了错误
TypeError:sum()无法对字符串求和[使用“”。改为join(seq)]
@interjay-yep,刚刚发现在编辑OP时,已相应修复谢谢,我想我已经理解了。:-)不过,要当心,这需要时间!由于
sum
始终使用
+
,如果您尝试将其用于列表串联,它将为每个中间串联构建一个新的中间列表,这需要二次复制。@NeilG:问题是它仍然需要在每个
+
上重新分配。如果不允许就地操作,则将大小加倍不会保存任何重新分配,并且
sum
不允许就地操作。一个潜在的改进是在第一次添加时使用
+
,在后续添加时使用
+=
,因为可能可以删除第一次
+
的结果。不过,我不确定这是否会引起问题,我怀疑这样的改变会得到多少支持。你会感到奇怪,比如
sum([[],(),[])
工作和
sum([(),[],[])
失败。谢谢你,我想我已经理解了。:-)谢谢,我想我已经明白了。:-)