用下面的语法阅读有关堆栈溢出的问题
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
内容作为一个块进行范围划分,而不是这样。通常情况下,这不是问题,而且很容易解决。