Pythonのリスト内包のスコープ
http://d.hatena.ne.jp/EnogunoCap/20080703/1215056587
「Pythonで遊んでたら疑問点が・・・」を見ていたら
C#で同じ話があったことを思い出しました。
http://www.atmarkit.co.jp/fdotnet/csharp20/csharp20_05/csharp20_05_02.html
上のリンク先で載ってました。
問題は、結局関数オブジェクト(lambda式)でループ変数を
そのまま利用していることなので、
解決策はリンク先と同じく一度別な変数に代入することで
うまくいきます。
でも、Pythonのlambda式は代入が使えません!!
代入に似た処理を・・・といろいろ試した結果
キーワード引数デフォルト引数が代入になることがわかりました!!
>>> lams = [ lambda l,m : l * x + m for x in range(10) ] >>> [ lam( 1, 5 ) for lam in lams ] [14, 14, 14, 14, 14, 14, 14, 14, 14, 14]
同じ数値が並ぶ結果となるところを、一度yに代入することによって
>>> lams = [ lambda l,m,y=x : l * y + m for x in range(10) ] >>> [ lam( 1, 5 ) for lam in lams ] [5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
となります。
ちなみに、Python3.0b1ではxは[ ]内のみのスコープとなっているようで
xと打つとエラーとなります。
>>> x Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'x' is not defined >>>
微妙に仕様が変わっているようです。*1
*1:2.x系のソースを全自動で3.0仕様にコンバートするって言ってるけど大丈夫かなぁ