python:关于lambda和闭包



我知道:

a=[lambda :k for k in [1,2,3]]
[e() for e in a]

返回[3, 3, 3],因为它在运行时取k的值,而k的最后一个值是3。然而,我不明白为什么,如果我这样做:

k=50
[e() for e in a]

我仍然得到[3, 3, 3]。为什么这样?我用50更新了k的值,为什么e()函数仍然读取旧的k值?

虽然你刚才说这很清楚,但

a=[lambda :k for k in [1,2,3]]
[e() for e in a]

返回[3,3,3],这需要几个字。当然,这并不是每个人都清楚的。第一个列表理解创建了三个函数。它们都不接受自变量,都返回变量k。在列表中,理解k不是一个数字。K是一个变量。您的三个函数返回该变量。所以你有三个相同的函数。通常情况下,k变量会丢失。它只适用于列表理解。在列表理解之外,您不能再访问它了。但在你的特殊情况下,k仍然活着。它仍然被捕获在三个函数中,因为它们返回它。这就是所谓的(k的(闭包。正如k在最后迭代列表[1,2,3]一样,它仍然是3。所以这三个函数都返回3。但这并不那么明显。Python也可以将其重新设置为零或随机数。不存在这样一种说法,即k保持在最后一个值。因此,即使您的代码返回[3,3,3],这也是不明显的,也不能保证。

如前所述,在列表理解之外,k不再可访问。它仅在列表理解的范围内。只有有了这三个a函数,你才能访问那个k。另一方面,你不能告诉a函数使用另一个k。列表理解中的k在它们的闭包中。k=50具有完全不同的范围。

如果你想要a函数中的其他k,你必须这样定义它们:

a=[lambda k : k_compr for k_kompr in [1,2,3]]
[e() for e in a]

然后把k传给他们。但我认为你的问题只是说说而已。没有人会用这样的清单来理解。

最新更新