首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么调用一个由for循环创建的短链lambda会导致RecursionError,而如果手动创建它的话,它会正常工作?

为什么调用一个由for循环创建的短链lambda会导致RecursionError,而如果手动创建它的话,它会正常工作?
EN

Stack Overflow用户
提问于 2020-10-12 19:41:33
回答 2查看 38关注 0票数 0

考虑到不同的结果,我看不出for版本和手册版本之间有什么相关的区别:

代码语言:javascript
运行
复制
# MANUAL version ==============================
lst = [lambda: 2]
lst.append(lambda: 2 * lst[0]())
lst.append(lambda: 2 * lst[1]())
lst.append(lambda: 2 * lst[2]())

print([item.__name__ for item in lst])
# ['<lambda>', '<lambda>', '<lambda>', '<lambda>']

print("result:", lst[-1]())
# result: 16

# FOR version ==============================
lst = [lambda: 2]
for i in range(3):
    print(i)
    lst.append(lambda: 2 * lst[i]())

print([item.__name__ for item in lst])
# ['<lambda>', '<lambda>', '<lambda>', '<lambda>']

print("result:", lst[-1]())
# 0
# 1
# 2
# RecursionError: maximum recursion depth exceeded
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-12 21:19:59

这里的问题是i变量。您需要绑定每个lambda的变量。您可以使用以下语法来完成此操作:lambda bound_i=i: 2 * lst[bound_i]()

通过这个,我得到了想要的结果。result: 16

我还发现这个问题类似于你的问题:Python Lambda in a loop。这比我的回答要深入得多,所以可能值得一读。

票数 1
EN

Stack Overflow用户

发布于 2020-10-12 21:20:22

排在队伍里

代码语言:javascript
运行
复制
    lst.append(lambda: 2 * lst[i]())

lambdas‘捕获’或关闭变量lsti,而不是它们的值。

在循环的末尾,i的值为2,除第一个元素外,lst中的所有元素都是返回2 * lst[2]() (包括lst[2] )的lambda。因此,评估lst[2]()需要对lst[2]()进行评估,这需要评估lst[2](),等等。

修复方法是在函数中创建lambda:

代码语言:javascript
运行
复制
def makeLambda(i):
    return lambda: 2 * lst[i]()

lst = [lambda: 2]
for i in range(3):
    print(i)
    lst.append(makeLambda(i))

这样做的原因是,每次对makeLambda的调用都会创建一个新的作用域,为每个lambda设置新的局部变量。在每个单独的函数调用中,i的值不会改变,因此这会产生您期望的结果。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64324392

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档