在Python中,为什么列表推导中的lambdas会在回顾中覆盖自己?

时间:2015-09-15 21:03:35

标签: python list function lambda list-comprehension

请考虑以下代码:

def f (a):
    return 1
def g (a):
    return 2

[lambda a: i(a) for i in (f,g)][0](0)

结果是2.它应该清楚为1!我希望这段代码执行如下。创建一个列表。将函数f复制到第一个索引中。将g复制到第二个索引中。鳍。

为什么这会按照它的方式执行?!

2 个答案:

答案 0 :(得分:4)

lambda没有覆盖自己,被i覆盖了。这是关于可变范围的常见错误。试试这个:

[lambda a, i=i: i(a) for i in (f,g)][0](0)

(差异是在创建lambda时绑定i的值)

另见:

答案 1 :(得分:1)

我会稍微扩展@ dsh的答案。

列表理解表达式

[lambda a: i(a) for i in (f,g)]

被评估,它创建两个匿名函数,每个函数都是

的效果
def _______(a):
    return i(a)

但是,在评估了上面的列表推导之后,名称i被绑定到它的最后一个迭代值,即绑定到g的对象,即你的第二个函数。

现在,之后,当列表中的一个匿名函数被调用时,它会访问名称i,它位于模块全局范围内且绑定与g相同的是

编辑:哦,@ dsh也扩展了它。