1

重複の可能性:
(ラムダ) 関数クロージャーは Python で何をキャプチャしますか?

このコードで:

def problem():
    PHI_LIST_0 = [lambda a, b: a+b+u for u in xrange(3)]
    PHI_LIST_1 = [lambda a, b: a+b+0, lambda a, b: a+b+1, lambda a, b: a+b+2]

    for phi in PHI_LIST_0: print "v0:", phi(1,1)
    print
    for phi in PHI_LIST_1: print "v1:", phi(1,1)

if __name__ == '__main__':
    problem()

私は得る:

v0: 4
v0: 4
v0: 4

v1: 2
v1: 3
v1: 4

予想される動作は、PHI_LIST_1 の最後の動作です。結果が PHI_LIST_0 で異なる理由を理解していると思います。おそらく、Python は phi(1,1) が評価されるときに最後の「u」、つまり 2 を使用するためです。

しかし、リスト内包表記を使用して、PHI_LIST_0 が定義されている方法で関数のリストを宣言したいと思います。どうすればそれができるか知っている人はいますか?

4

1 に答える 1

2

関数を定義すると、関数本体の自由変数に対してクロージャが作成されます。あなたの PHI_LIST_0 では、それが variable ですu。u の値を保持するのではなく、名前 u への参照を保持します。関数を呼び出すと、u の現在の値が使用されます。したがって、すべての関数が同じ変数を参照し、すべてが同じ (最後の) 値を参照するため、すべて同じように動作します。

これは、デフォルト値のトリックで解決できます。

PHI_LIST_0 = [lambda a, b, u=u: a+b+u for u in xrange(3)]

u パラメータのデフォルト値は、関数が定義されたときに計算され、関数とともに保存されます。

于 2012-12-11T15:45:24.040 に答える