TypeError: 'int' 对象在使用 reduce 和 lambda 时不可调用
Posted
技术标签:
【中文标题】TypeError: \'int\' 对象在使用 reduce 和 lambda 时不可调用【英文标题】:TypeError: 'int' object is not callable when using reduce and lambdaTypeError: 'int' 对象在使用 reduce 和 lambda 时不可调用 【发布时间】:2021-10-05 11:09:34 【问题描述】:from functools import reduce
lists = [lambda x: x+5, lambda x: x+6, lambda x: x+7]
n = 5
print(list(reduce(lambda a, b: a(n) + b(n), lists)))
我不确定为什么会收到错误“TypeError: 'int' object is not callable”
【问题讨论】:
您期望的结果是什么?你知道reduce
实际做了什么吗?具体来说,您希望a
在每个步骤中的类型/值是什么?
我希望它使用列表[] 中的 lambda 函数。我认为最终结果应该打印 23
但是a(n) + b(n)
将返回一个int
对象,它会作为a
传递给下一次迭代...所以当您执行some_int(n) + b(n)
.. ..你得到错误
【参考方案1】:
a
和 b
都是函数,但只有 b
保证是列表参数中的函数。 a
是上一次调用reduce
第一个参数的最后一次调用的结果。您想使用函数组合来减少 lists
。
>>> reduce(lambda a, b: lambda n: b(a(n)), lists)(5)
23
(在这种特殊情况下,a(b(n))
的工作方式相同,因为所有三个函数都涉及相同的可交换操作,所以组合也是可交换的。不过,一般来说,a
绑定到第一个函数并且b
第一次迭代中的第二个;之后,a
绑定到结果,b
绑定到列表中的下一个函数。)
要使其与空列表一起使用,您需要提供标识函数 (lambda x: x
) 作为初始值,因为这是函数组合的标识:
>>> reduce(lambda a, b: lambda n: b(a(n)), [])(5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: reduce() of empty sequence with no initial value
>>> reduce(lambda a, b: lambda n: b(a(n)), [], lambda x: x)(5)
5
【讨论】:
【参考方案2】:reduce
使用之前调用函数的结果作为下一次调用的输入之一。该函数在您第一次调用它时返回一个int
,因此第二次调用它时,它的两个参数是该 int 和另一个函数——而一个 int 不是您提供的归约函数的有效参数(它需要两个函数),所以你会得到那个错误。
【讨论】:
【参考方案3】:您需要为reduce
提供一个初始值,并在以后累积其他值。
reduce(lambda acc, b: acc + b(n), lists, 0)
或者,我们可以将其拆分为两个操作:map
和 reduce
。
reduce(lambda a, b: a + b, map(lambda f: f(n), lists), 0)
reduce
与 +
和 0
只是 sum
,所以我们可以将其缩短为
sum(map(lambda f: f(n), lists))
或者,等价
sum(f(n) for f in lists)
【讨论】:
reduce(lambda a, b: a + b, map(lambda f: f(n), lists)) 不会导致错误但它仍然不会返回正确的数字 OP 中提出的问题涉及将结果相加。如果这不是所需的行为,请编辑问题以反映这一点。 我们确实想将结果相加,但在 OP 中结果应该是 23,但使用您的代码返回 33 如果您期望 23,那么您确实不想要将结果相加。你想要函数组合,然后去阅读 chepner 的答案。以上是关于TypeError: 'int' 对象在使用 reduce 和 lambda 时不可调用的主要内容,如果未能解决你的问题,请参考以下文章
TypeError:'int'对象不可迭代,使用 Python 3 [关闭]
TypeError:int() 参数必须是字符串、类似字节的对象或数字,而不是“DataFrame”