reduce(x+;y,xs)和sum(xs)在python中不等价吗?
然而,从函数等式的角度来看,我认为这两个词的意思是相同的:reduce(x+;y,xs)和sum(xs)在python中不等价吗?,python,sum,tuples,reduce,equational-reasoning,Python,Sum,Tuples,Reduce,Equational Reasoning,然而,从函数等式的角度来看,我认为这两个词的意思是相同的: x = [1, 2, 3] y = ['a', 'b', 'c'] reduce(lambda x, y: x + y, zip(x, y)) # works sum(zip(x, y)) # fails 为什么sum在这里失败?实际问题是,sum的默认起始值。引用 将iterable的起始项和项从左到右求和,并返回总数开始默认为0。iterable的项通常是数字,并且起始值不允许是字符串 但是,在reduce的情况下,如果没
x = [1, 2, 3]
y = ['a', 'b', 'c']
reduce(lambda x, y: x + y, zip(x, y)) # works
sum(zip(x, y)) # fails
为什么
sum
在这里失败?实际问题是,sum
的默认起始值。引用
将iterable的起始项和项从左到右求和,并返回总数开始默认为0
。iterable的项通常是数字,并且起始值不允许是字符串
但是,在reduce
的情况下,如果没有给出可选的起始值,它将使用iterable中的第一个值作为初始值设定项。所以,reduce
实际上是这样计算的
( ( (1, 'a') + (2, 'b') ) + (3, 'c') )
>>> sum(zip(x, y), tuple())
(1, 'a', 2, 'b', 3, 'c')
() + (1, 'a') + (2, 'b') + (3, 'c')
>>> tuple(item for items in zip(x, y) for item in items)
(1, 'a', 2, 'b', 3, 'c')
由于sum
假定起始值为0,因此它的计算方式如下:
0 + (1, 'a') + (2, 'b') + (3, 'c')
在本例中,它尝试使用一个元组添加0
,这就是您得到
TypeError:不支持+:'int'和'tuple'的操作数类型
要解决此问题,请将一个空元组传递给sum
,如下所示
( ( (1, 'a') + (2, 'b') ) + (3, 'c') )
>>> sum(zip(x, y), tuple())
(1, 'a', 2, 'b', 3, 'c')
() + (1, 'a') + (2, 'b') + (3, 'c')
>>> tuple(item for items in zip(x, y) for item in items)
(1, 'a', 2, 'b', 3, 'c')
现在,初始值是一个空元组,计算过程如下
( ( (1, 'a') + (2, 'b') ) + (3, 'c') )
>>> sum(zip(x, y), tuple())
(1, 'a', 2, 'b', 3, 'c')
() + (1, 'a') + (2, 'b') + (3, 'c')
>>> tuple(item for items in zip(x, y) for item in items)
(1, 'a', 2, 'b', 3, 'c')
注意:在这两种情况下,将创建多个中间元组。为了避免这种情况,我建议将数据展平,并将其作为生成器表达式传递给tuple
构造函数,如下所示
( ( (1, 'a') + (2, 'b') ) + (3, 'c') )
>>> sum(zip(x, y), tuple())
(1, 'a', 2, 'b', 3, 'c')
() + (1, 'a') + (2, 'b') + (3, 'c')
>>> tuple(item for items in zip(x, y) for item in items)
(1, 'a', 2, 'b', 3, 'c')
这让人觉得
sum
实际上是设计错误的:start
应该默认为第一项,而不是0
@thefourtheye啊,非常好的捕获,关于初始值;我不知道您可以传递自定义的起始值。对于sum(zip(x,y),tuple())
我仍然得到“TypeError:无法使用灵活类型执行reduce”。你知道为什么吗?@georg那么sum([])
会是什么?@HenryHenrinsonTypeError
withreduce
或sum
?@HenryHenrinson你使用的是哪个版本的Python?我试过Py 2.7和3.4,两个都很好