reduce(x+y, xs) 和 sum(xs) 在 python 中不等价?
reduce(x+y, xs) and sum(xs) are not equivalent in python?
但是,从函数方程式的角度来看,我希望两者的意思相同:
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
的默认起始值。引用 documentation,
Sums start and the items of an iterable from left to right and returns the total. start defaults to 0
. The iterable‘s items are normally numbers, and the start value is not allowed to be a string.
但是,在 reduce
的情况下,如果没有给出可选的起始值,它将使用可迭代对象中的第一个值作为初始值设定项。所以,reduce
其实是这样评价的
( ( (1, 'a') + (2, 'b') ) + (3, 'c') )
由于sum
假设起始值为0,所以它是这样计算的,
0 + (1, 'a') + (2, 'b') + (3, 'c')
在这种情况下,它会尝试使用元组添加 0
,这就是为什么您会得到
TypeError: unsupported operand type(s) for +: 'int' and 'tuple'
要解决这个问题,将一个空元组传递到 sum
的开头,就像这样
>>> sum(zip(x, y), tuple())
(1, 'a', 2, 'b', 3, 'c')
现在,初始值是一个空元组,评估是这样发生的
() + (1, 'a') + (2, 'b') + (3, 'c')
注意:在这两种情况下,都会创建多个中间元组。为避免这种情况,我建议展平数据并将其作为生成器表达式传递给 tuple
构造函数,例如
>>> tuple(item for items in zip(x, y) for item in items)
(1, 'a', 2, 'b', 3, 'c')
但是,从函数方程式的角度来看,我希望两者的意思相同:
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
的默认起始值。引用 documentation,
Sums start and the items of an iterable from left to right and returns the total. start defaults to
0
. The iterable‘s items are normally numbers, and the start value is not allowed to be a string.
但是,在 reduce
的情况下,如果没有给出可选的起始值,它将使用可迭代对象中的第一个值作为初始值设定项。所以,reduce
其实是这样评价的
( ( (1, 'a') + (2, 'b') ) + (3, 'c') )
由于sum
假设起始值为0,所以它是这样计算的,
0 + (1, 'a') + (2, 'b') + (3, 'c')
在这种情况下,它会尝试使用元组添加 0
,这就是为什么您会得到
TypeError: unsupported operand type(s) for +: 'int' and 'tuple'
要解决这个问题,将一个空元组传递到 sum
的开头,就像这样
>>> sum(zip(x, y), tuple())
(1, 'a', 2, 'b', 3, 'c')
现在,初始值是一个空元组,评估是这样发生的
() + (1, 'a') + (2, 'b') + (3, 'c')
注意:在这两种情况下,都会创建多个中间元组。为避免这种情况,我建议展平数据并将其作为生成器表达式传递给 tuple
构造函数,例如
>>> tuple(item for items in zip(x, y) for item in items)
(1, 'a', 2, 'b', 3, 'c')