4
l = [1, 2, 3]
a,b,c = [lambda: n*n for n in l]
a() #=> 9
b() #=> 9
c() #=> 9
這是爲什麼?我期望a(),b(),c()是1,4和9.在詞典理解中受到詞彙封閉困惑
l = [1, 2, 3]
a,b,c = [lambda: n*n for n in l]
a() #=> 9
b() #=> 9
c() #=> 9
這是爲什麼?我期望a(),b(),c()是1,4和9.在詞典理解中受到詞彙封閉困惑
n
不在函數的本地關閉中。
嘗試
a, b, c = [lambda n=n: n*n for n in l]
此默認參數的「濫用」使每個功能
這裏可以創建一個名爲n
一個局部變量是另一種方式在Python2
>>> L=[1, 2, 3]
>>> def fgen():
... local_n = global_n
... def f():
... return local_n * local_n
... return f
>>> a, b, c = [fgen() for global_n in L]
>>> a()
1
>>> b()
4
>>> c()
9
創建一個封閉
它不會在Python3中工作,因爲列表理解中的循環變量不會泄漏到全局範圍內
Python3確實阻止我們在功能使用全局的一個更好的工作,所以你需要傳遞一個參數,如果你想用一個列表理解
>>> L=[1, 2, 3]
>>> def fgen(param_n):
... local_n = param_n
... def f():
... return local_n * local_n
... return f
...
>>> a, b, c = [fgen(n) for n in L]
>>> a()
1
>>> b()
4
>>> c()
9
>>>
類似這樣的'[lambda x = n:x * x for n in l]'不太令人困惑。 –
[在Python古怪的封閉行爲]的可能重複(http://stackoverflow.com/questions/11109838/weird-closure-behavior-in-python) –
在迭代結束時'n'的值是3,而你實際上使用了全局變量'n'在你的lambda中。所以,每次你調用一個(),b()或c()時,他們都會尋找一個全局變量'n'。迭代後嘗試'del n',然後調用(),b()或c()。 –
@AshwiniChaudhary - 小心點。在python3.x中,當你嘗試'del n'時(假設它以前沒有定義過...),你會得到一個'NameError'。但你對python2.x會發生什麼是正確的... – mgilson