为什么这段代码打印的是“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/