![](/img/trans.png)
[英]What does "TypeError: unsupported operand type(s) for +: 'int' and 'tuple'" mean when using built-in sum function?
[英]What does the built-in function sum do with sum(list, [])?
当我想展开一个列表时,我找到了如下方式:
>>> 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])
Sums从左到右
start
和iterable
的项目并返回总数。start
默认为0
。 可迭代的项目是正常的数字,并且start
值不允许是一个字符串。对于某些用例,
sum()
有很好的替代方法。 连接字符串序列的首选快速方法是调用''.join(sequence)
。 要以扩展精度添加浮点值,请参阅math.fsum()
。 要连接一系列迭代,请考虑使用itertools.chain()
。版本2.3中的新功能。
难道你不认为开始应该是一个数字? 为什么[]
在这里写的?
(sum(a, []))
难道你不认为开始应该是一个数字?
默认情况下, 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'
因为它现在正在做0 + ['foo'] + ['bar']
。
要解决这个问题,你可以将自己的start
作为[]
,因此它会变成[] + ['foo'] + ['bar']
,一切都很好。 所以回答:
为什么
[]
可以写在这里?
因为虽然start
默认为一个数字,它并没有成为一个; 其他东西也可以添加,这对于你正在做的事情来说非常方便。
首先,永远不要使用sum
来连接/展平列表,因为它具有二次时间,因此与其他方式相比根本没有效率。 它实际上使用了画家算法的schlemiel 。
sum
函数在每次迭代时调用start
的__add__
属性,并将迭代的所有项作为第一个参数传递。
例如 :
>>> [].__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]
并不是说您可以在具有__add__
属性的任何对象序列上调用sum
函数,但请注意,如果您的对象不是整数,则默认的start
参数为0
,它将引发TypeError
。 在这种情况下,您需要为该函数指定正确的start
。
>>> 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'
您将start
与您提供的可迭代内容作为第一个参数相加。 sum
不限制int的start
type
,以允许各种添加情况。
基本上sum是这样的:
a = [[1, 2], [3, 4], [5, 6]]
sum(a, number)
大致翻译为:
number += every value in the list a
由于列表a
中的每个值都是一个列表,因此扩展时的前一个求和看起来像这样:
number + [1, 2] + [3, 4] + [5, 6]
因此,如果输入int
这将导致不幸的TypeError
因为不允许添加int
和list
。
1 + [1, 2] == I hope you like TypeErrors
但是,如果你输入一个列表[]
它只是要的元素加入a
一起,导致我们所知道的扁平列表和爱。
start
值默认为0
和int
主要是因为最常见的求和情况是算术。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.