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
>>>