python - 在循环(或理解)中创建函数(或 lambda)

标签 python

我正在尝试在循环内创建函数:

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/

相关文章:

Python:变量范围和 profile.run

python - 将 AND 和 OR 与 Q 对象组合的 Django 查询过滤器不返回预期结果

python - 如何在 Pandas 中使用countif添加一行

python - 从关键事件中获取特殊字符

Python:为什么 plot_surface 是透明的?

python - SUDS:在 Client.service 方法中传递数组参数:GAE Python

python - 将多索引数据框中的所有匹配元素设置为系列

python - Pandas:检查系列 A 中的单词是否以系列 B 中的一个单词结尾的最快方法

python - 在django中查询时间戳字段

python - 'python setup.py bdist'在 'compiler_flags'上获取错误