重複の可能性:
Python ラムダとスコープ
私は、以下が値0、1、および2を取る3つの定数関数のリストを生成することを望んでいます:
lis = []
for i in range(3):
lis.append( lambda: i )
しかし、それらはすべて値2を取ることになります。ディープコピーで問題を解決できると思いますが、うまくいかないようです。
重複の可能性:
Python ラムダとスコープ
私は、以下が値0、1、および2を取る3つの定数関数のリストを生成することを望んでいます:
lis = []
for i in range(3):
lis.append( lambda: i )
しかし、それらはすべて値2を取ることになります。ディープコピーで問題を解決できると思いますが、うまくいかないようです。
次のような記述を避けるためにループします。
lis.append( lambda: 0 )
lis.append( lambda: 1 )
lis.append( lambda: 2 )
あなたの意図は、定数整数を返すラムダ関数を書くことです。しかし、 object を返す関数を定義して追加していますi
。したがって、3 つの追加機能は同じです。
作成された関数の背後にあるバイト コードは次を返しますi
。
In [22]: import dis
In [25]: dis.dis(lis[0])
3 0 LOAD_GLOBAL 0 (i)
3 RETURN_VALUE
In [26]: dis.dis(lis[1])
3 0 LOAD_GLOBAL 0 (i)
3 RETURN_VALUE
In [27]: dis.dis(lis[2])
3 0 LOAD_GLOBAL 0 (i)
3 RETURN_VALUE
これらの関数のいずれかを呼び出すと、サンプル コードにある最新の値が返されi
ます。2
In [28]: lis[0]()
Out[28]: 2
オブジェクトを削除するi
と、エラーが発生します。
In [29]: del i
In [30]: lis[0]()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-30-c9e334d64652> in <module>()
----> 1 lis[0]()
<ipython-input-18-15df6d11323a> in <lambda>()
1 lis = []
2 for i in range(3):
----> 3 lis.append( lambda: i )
NameError: global name 'i' is not defined
解決策は、ループを使用して必要な定数でコードを記述し、実際にそのコードを実行することです。
In [31]: lis = []
...: for i in range(3):
...: exec 'lis.append( lambda: {} )'.format(i)
...:
次の結果が得られます。
In [44]: lis[0]()
Out[44]: 0
In [45]: lis[1]()
Out[45]: 1
In [46]: dis.dis(lis[0])
1 0 LOAD_CONST 1 (0)
3 RETURN_VALUE
In [47]: dis.dis(lis[1])
1 0 LOAD_CONST 1 (1)
3 RETURN_VALUE