2016-10-15 5 views
1

私はkey=keyは、この単純なPythonのコードで何を見つけることができません。厄介なラムダ関数

for key in dict: 
    f = (lambda key=key: print(key)) 
    print(f()) 
+0

ラムダ関数に 'key'イテレータを渡しています。実際には、正確に何が起こっているのかをもう少し明確にするために、 'lambda foo = key:print(foo)'としていたかもしれません。また、あなたの 'key'をかなり印刷するラムダがあるので' print(f()) 'は冗長で' None'と表示されます。だから、あなたは 'f()'を呼び出す必要があります。しかし、これはキーを印刷するための非常に奇妙なデザインの選択です。単純に 'print(key)'というだけではなく、 – idjaw

+0

.whyがキーに戻ってキーを割り当てるのはなぜですか? "key = key" ....誰がそれを書いたのですか?.....コーダーが疲れていた可能性があります... lol – repzero

+0

@repzeroキーにキーを戻していません。ラムダは単一の引数をとり、その引数は 'key'と命名されました。名前は実際には実際のイテレータ 'key'とは関係ありません。私のコメントで説明したように、 'foo = key'だったでしょう。 – idjaw

答えて

3

このコードkey=keyはまったく役に立たない。あなただけのようにもこれは12、および3を印刷します

for key in [1,2,3]: 
    f = lambda: key 
    print(f()) 

としてループを書くことができます。 (問題とは無関係に、lambdaからprintを削除し、その値を冗長にして返すようにしました。printはで返されるようになりました。None 。)

しかし、ループ内で右の関数を実行しないのはどうですか?それは価値がある場合、それがすなわちループの後、をに定義されている場合機能はは、と呼ばれていない場合key変数が評価されるよう

functions = [] 
for key in [1,2,3]: 
    f = lambda: key 
    functions.append(f) 

for f in functions: 
    print(f()) 

さて、これは、33、および3を印刷します3。これはいくつかの重大な驚きを引き起こす可能性があります。 defining callback functions for different buttons in a loopkey=keyを使用してここで

は、場に出た:関数がデフォルト値としてを定義した場合、このループkey変数の現在の値をパラメータkeyを作成し、それに割り当てられます(したがって、あなたがする必要はありません関数を呼び出すときにパラメータを渡します)。関数は、後に呼び出されたときにそのkey paremeterの値は、関数の範囲内で同じとどまります:

functions = [] 
for key in [1,2,3]: 
    f = lambda key=key: key 
    functions.append(f) 

これは予想されるように、12、および3を出力します。他の人が指摘しているように、このパラメータを別の名前にすると、これを混乱を避けることができます。 f = lambda param=key: param

0

「キー=キー」の最初のキーは、ラムダ関数の引数の名前です。 2番目のキーはローカル変数です。あなたの場合はforループ変数です。

したがって、各反復でローカルキー変数が定義されていると、fはこのローカルと同じデフォルトの1つの引数を受け取るラムダ関数として定義されます。したがって、print(キー)はこのデフォルト値。

編集: f()のコンテキストでは、keyはforループ変数ではなく、ローカルのf引数であることを強調する必要があります。ループ変数の値がデフォルトになります。

EDIT 2: idjawさんのコメントに気付いたばかりです。私はこれが答えだとは思わないが、これがあなたのコードを書いたはずである。

+0

ただのヒント。あなたの答えを編集するときは、あなたがすでに書いたものをさらに明快にするために変更することも自由です。編集内容を最後に追加する必要はありません。 – idjaw

+0

ありがとう、ここでは新しいのでベストプラクティスについてはわかりませんでした。今からやるよ。 – kabanus

+0

あなたがより良い答えを改善している限り、それを続けることを自由にしてください。あなたが好きなら今でも。ようこそ! :) – idjaw

2

このコードは「シンプル」ではありませんが、実際にはPythonの初心者にとってはやや難解です。

for key in dict:は、単にdictをループします。通常dictは、あらかじめ定義されたシステムライブラリクラス(標準辞書のクラス)であり、クラスオブジェクトの反復処理は(通常は)ナンセンスです。

dictがバインドされているものを再定義することができます。dictはキーワードではなく、好きなように再利用できる単なる名前です。IDEや他のプログラマを混乱させる悪質なPythonコードを書いてください。

この文脈では、dictは、繰り返し処理できる何らかのコンテナであると仮定します。たとえば、リスト、タプルまたは辞書(名前が示すとおり)です。辞書を反復処理するということは、Pythonでは辞書キーを反復処理することを意味しています。

f = (lambda key=key: print(key)) 

このコードはkeyというパラメータを受け入れる無名関数を作成し、ループ内で使用される変数keyの現在の値にデフォルト値を定義します。関数の本体は、標準でprint関数を引数としてkeyに渡します。ことを回避するには、同じ名前を再利用するため、おそらく、初心者のためのビット明確である

f = lambda x=key: print(x) 

コードは同等です。

最後に、この関数はパラメータを渡さずに呼び出され、結果はprint標準関数に送信されます。 f()の評価では、keyの値が出力されます(パラメータを渡さずにデフォルト値が使用されます)。print(つまりNone)の結果は、2回目のprint呼び出しで印刷されます。

この例では本当に良いことはありません。実際にはlambda x=x:...はPythonのパターンであり、時には必要ですが、ここでは完全なナンセンスであり、この使い方から学ぶことは何もありません。

あなたはこれを持っているソースから読み続けることを再考する必要があります(残りは悪いことだと思います)。より良い例については公式のチュートリアルに固執してください...

関連する問題