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】:

ab 都是函数,但只有 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)

或者,我们可以将其拆分为两个操作:mapreduce

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'对象在运行多处理时不可调用

TypeError:'int'对象在odoo中不可迭代

TypeError:int() 参数必须是字符串、类似字节的对象或数字,而不是“DataFrame”

TypeError:无法在 Django 视图函数中解压不可迭代的 int 对象

导致 TypeError 的 Lambda 函数:“int”对象不可迭代