用下面的语法阅读有关堆栈溢出的问题

In [1]: [lambda: x for x in range(5)][0]()
Out[1]: 4
In [2]: [lambda: x for x in range(5)][2]()
Out[2]: 4

但我很难理解为什么这个结果精确到4,
我的理解是,它总是将列表的最后一个值作为输出,
In [4]: [lambda: x for x in [1,5,7,3]][0]()
Out[4]: 3

但是仍然不相信这个语法是如何以最后一个值结束的。
如果我能对这个语法有一个适当的解释,我会很高兴的

最佳答案

这既不是关于清单理解,也不是关于lambdas。这是关于Python中的作用域规则。让我们将列表理解重写为等效循环:

funcs = []
for x in range(5):
    def f(): return x
    funcs.append(f)
funcs[0]() # returns 4

在这里,我们可以看到我们依次构造函数并将它们存储在一个列表中。当调用其中一个函数时,只会查找并返回x的值。但是,x是一个变量,其值会发生变化,因此,4的最终值始终是返回值。您甚至可以在循环之后更改x的值,例如,
x = 32
funcs[2]() # returns 32

要获得您预期的行为,python需要将for内容作为一个块进行范围划分,而不是这样。通常情况下,这不是问题,而且很容易解决。

09-10 23:03