我正在尝试在循环内创建函数:
functions = []
for i in range(3):
def f():
return i
# alternatively: f = lambda: i
functions.append(f)
问题是所有函数最终都是一样的。三个函数都返回 2,而不是返回 0、1 和 2:
print([f() for f in functions])
# expected output: [0, 1, 2]
# actual output: [2, 2, 2]
为什么会这样,我应该怎么做才能得到 3 个分别输出 0、1 和 2 的不同函数?
最佳答案
您遇到了后期绑定(bind)的问题——每个函数都尽可能晚地查找i
(因此,在循环结束后调用时, i
将被设置为 2
)。
通过强制早期绑定(bind)轻松修复:将 def f():
更改为 def f(i=i):
,如下所示:
def f(i=i):
return i
默认值(i=i
中右边的 i
是参数名称 i
的默认值,这是左边的 - hand i
in i=i
) 在def
时间被查找,而不是在call
时间,所以本质上他们'是一种专门寻找早期绑定(bind)的方法。
如果您担心 f
得到一个额外的参数(因此可能被错误调用),有一种更复杂的方法涉及使用闭包作为“函数工厂”:
def make_f(i):
def f():
return i
return f
并在您的循环中使用 f = make_f(i)
而不是 def
语句。
关于python - 在循环(或理解)中创建函数(或 lambda),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26519315/