重い計算の一種のキャッシュとして機能するラムダのリストが欲しかったのですが、次のことに気付きました。
>>> [j() for j in [lambda:i for i in range(10)]]
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
それでも
>>> list([lambda:i for i in range(10)])
[<function <lambda> at 0xb6f9d1ec>, <function <lambda> at 0xb6f9d22c>, <function <lambda> at 0xb6f9d26c>, <function <lambda> at 0xb6f9d2ac>, <function <lambda> at 0xb6f9d2ec>, <function <lambda> at 0xb6f9d32c>, <function <lambda> at 0xb6f9d36c>, <function <lambda> at 0xb6f9d3ac>, <function <lambda> at 0xb6f9d3ec>, <function <lambda> at 0xb6f9d42c>]
つまり、ラムダは一意の関数ですが、どういうわけかすべて同じインデックス値を共有しています。
これはバグですか、それとも機能ですか? この問題を回避するにはどうすればよいですか? リスト内包表記に限定されません...
>>> funcs = []
... for i in range(10):
... funcs.append(lambda:i)
... [j() for j in funcs]
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]