考虑到不同的结果,我看不出for版本和手册版本之间有什么相关的区别:
# 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发布于 2020-10-12 21:19:59
这里的问题是i变量。您需要绑定每个lambda的变量。您可以使用以下语法来完成此操作:lambda bound_i=i: 2 * lst[bound_i]()
通过这个,我得到了想要的结果。result: 16
我还发现这个问题类似于你的问题:Python Lambda in a loop。这比我的回答要深入得多,所以可能值得一读。
发布于 2020-10-12 21:20:22
排在队伍里
lst.append(lambda: 2 * lst[i]())lambdas‘捕获’或关闭变量lst和i,而不是它们的值。
在循环的末尾,i的值为2,除第一个元素外,lst中的所有元素都是返回2 * lst[2]() (包括lst[2] )的lambda。因此,评估lst[2]()需要对lst[2]()进行评估,这需要评估lst[2](),等等。
修复方法是在函数中创建lambda:
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的值不会改变,因此这会产生您期望的结果。
https://stackoverflow.com/questions/64324392
复制相似问题