12

ループで、2つのノードの2つのvalue()の比較を後で延期しようとしています。

class Node():
    def __init__(self, v):
        self.v = v
    def value(self):
        return self.v

nodes = [Node(0), Node(1), Node(2), Node(3), Node(4), Node(2)]
results = []
for i in [0, 1, 2]:
    j = i + 3
    results.append(lambda: nodes[i].value() == nodes[j].value())

for result in results:
    print result

結果はすべてTrueです(すべてのラムダに対してi、j == 2,5であるため)。ラムダの実行を実際に呼び出されるまで延期するにはどうすればよいですか?ただし、正しい変数バインディングを使用しますか?そして、ラムダの式は必ずしもすべてが等しいわけではありません...他にももっと複雑な式がたくさんあります。

助けてくれてありがとう!

4

3 に答える 3

17

関数の現在の値を外部スコープで検索する代わりに関数にバインドするにはijクロージャ値またはデフォルトの引数値のいずれかを使用できます。これを行う最も簡単な方法は、ラムダでデフォルトの引数値を使用することです。

for i in [0, 1, 2]:
    j = i + 3
    results.append(lambda i=i, j=j: nodes[i].value() == nodes[j].value())

クロージャーとしてどのように見えるかを次に示します。

def make_comp_func(i, j):
    return lambda: nodes[i].value() == nodes[j].value()

for i in [0, 1, 2]:
    j = i + 3
    results.append(make_comp_func(i, j))
于 2012-06-18T16:31:36.083 に答える
9

別のラムダでラップします。

results.append((lambda x, y: lambda: nodes[x].value() == nodes[y].value()) (i, j))

またはより良い方法で、partial

from functools import partial

results.append(partial(lambda x, y: nodes[x].value() == nodes[y].value(), i, j))

デフォルトの引数のトリックは、まあ...トリックです、そして私はそれを避けることをお勧めします。

于 2012-06-18T16:42:26.063 に答える
4

慣用的な方法は、デフォルトの引数を使用することです。

[f() for f in [lambda: i for i in range(3)]]
[2, 2, 2]

これを次のように変更します。

[f() for f in [lambda i=i: i for i in range(3)]]
[0, 1, 2]
于 2012-06-18T16:38:06.377 に答える