python - lambda 中的变量作用域

标签 python scope

为什么这段代码打印的是“d, d, d, d”,而不是“a, b, c, d”?如何修改它以打印“a、b、c、d”?

cons = []
for i in ['a', 'b', 'c', 'd']: 
    cons.append(lambda: i)  
print ', '.join([fn() for fn in cons])      

最佳答案

奇怪的是,这不是变量 scope 问题,而是 python 的 for 循环(以及 python 的变量)的语义问题。

如您所料,lambda 内部的 i 正确地引用了最近封闭范围内的变量 i。到目前为止,还不错。

但是,您希望这意味着会发生以下情况:

for each value in the list ['a', 'b', 'c', 'd']: 
    instantiate a new variable, i, pointing to the current list member
    instantiate a new anonymous function, which returns i
    append this function to cons

实际发生的是这样的:

instantiate a new variable i
for each value in the list ['a', 'b', 'c', 'd']: 
    make i refer to the current list member
    instantiate a new anonymous function, which returns i
    append this function to cons

因此,您的代码将 same 变量 i 附加到列表中四次——并且在循环退出时,i值为 'd'

请注意,如果 python 函数通过 value 获取并返回其参数/返回值的值,您将不会注意到这一点,因为 i 的 contents 将在每次调用 append 时被复制(或者,就此而言,在每次从使用 lambda 创建的匿名函数返回时)。然而,实际上,python 变量始终是对特定对象的引用——因此您的 i 的四个副本都引用了 'd'到那时你的循环结束。

关于python - lambda 中的变量作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14738844/

相关文章:

python - 在 AMPPS 中设置 Python - 内部服务器错误

python - 如何在 Django ORM 中进行通配符搜索以替换单个字符 (_)?

python - 在 exec 中用空局部变量列表理解 : NameError

ruby-on-rails - ActiveRecord 中 default_scope 的替代方案

python简单路由器url匹配器,如何重新匹配第一个 "/"出现

python - 如何让这个方 block 在 Tkinter 中消失

python - tensorflow 中的图循环

javascript - 隐式全局 "item"变量 - Internet Explorer 和 FireFox 之间的差异

python - 为什么将classdef套件中的名称范围限制为不包括funcdef的关闭?

javascript - 为 JavaScript for 循环重用 "i"