2

私は次のことをしようとしています。これは、私の最終的な目標がどうなるかの代表的な例です:

 yu = lambda x: 0
 for i in range(0,5):
      yu = lambda x: i + yu(x)

残念ながら、次のように返されます。

RuntimeError: maximum recursion depth exceeded

私がする時:

print yu(0)

print ステートメントは 10 を返す必要があります。

これを行う正しい方法は何ですか?

4

5 に答える 5

5

最後に、あなたは持っています:

yu = lambda x: i + yu(x)

ただし、ラムダを作成したときではなく、実行時yuに検索されます。代わりにこれを行ってください:

for i in range(0,5):
    yu = lambda x, yu=yu: i + yu(x)

ただし、これは返されませ10。代わりに戻ります20

>>> yu = lambda x: 0
>>> for i in range(0,5):
...     yu = lambda x, yu=yu: i + yu(x)
... 
>>> yu(0)
20

なぜなら、今iはまだコンテキストから検索されているからです(そして、今ではループが終了しているので、そう4です)。解決?iキーワード引数にも移動します。

for i in range(0,5):
    yu = lambda x, yu=yu, i=i: i + yu(x)

これは動作します:

>>> yu = lambda x: 0
>>> for i in range(0,5):
...     yu = lambda x, yu=yu, i=i: i + yu(x)
... 
>>> yu(0)
10

この話の教訓?コンテキストをラムダのスコープに適切にバインドします。

于 2013-02-27T23:08:56.900 に答える
2
 yu = lambda x: i + yu(x)

これによりyu、常に自分自身を呼び出す関数になり、基本ケースのない無限再帰が保証されます。

なんで?さて、クロージャーを作成しました。ここで、yu(および) は、ループがi含まれる関数またはモジュール内のローカル変数です。forそれはあなたが望むものではありません。外部変数ではなく、との現在の値を閉じます。yui

そもそもなぜあなたが使っているのかさえわかりませんlambda。関数を定義して名前を付けたい場合は、 を使用しますdef

簡単な解決策は次のとおりです。

def yu(x): return 0
def make_new_yu(yu, i):
    def new_yu(x): return i + yu(x)
    return new_yu
for i in range(0, 5):
    yu = make_new_yu(yu, i)

ラッピングを明示的にすることで、それを行う正しい方法が最も明白な方法になります。

もちろん、混乱を招くことなくlambdainsideを使用できます。make_new_yu

def make_new_yu(yu, i):
    return lambda x: i + yu(x)

また、必要に応じて、初期定義を a にすることもできlambdaます。しかし、ステートメントを持たないことを主張する場合は defデフォルト値のトリックを使用するなど、何らかの方法で正しい値をクロージャーに強制する必要があります。これは間違いやすく、一度間違えると読みにくくなります。

詳細を学習せずに違いを直感的に理解したい場合は、関数本体で新しいスコープを定義します。したがって、その関数内で関数を (lambdaまたはでdef) 定義することは、クロージャーがその新しいスコープからのものであることを意味します。

于 2013-02-27T23:10:53.687 に答える
0

答えを考慮して、0、1、2、3、4 を合計しようとします。それが正しければ、次のラムダ式を使用できます。

yu = lambda x: x + yu(x+1) if x<4 else x

yu(0)結果として 10 が返されます。ブレーク条件は、x足し合わせるために 4 未満であることが必要な値です。

それがあなたのやりたいことであると仮定すると、かなり簡潔なステートメントのためにループを除外する必要があります。

このラムダ式は、指定された引数に応じて異なる値 (パラメータ x として 0 を選択しない場合は 10 以外) になるという点で他の式とは異なります。

于 2013-02-27T23:52:31.110 に答える