私はkey=key
は、この単純なPythonのコードで何を見つけることができません。厄介なラムダ関数
for key in dict:
f = (lambda key=key: print(key))
print(f())
私はkey=key
は、この単純なPythonのコードで何を見つけることができません。厄介なラムダ関数
for key in dict:
f = (lambda key=key: print(key))
print(f())
このコードkey=key
はまったく役に立たない。あなただけのようにもこれは1
、2
、および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())
さて、これは、3
、3
、および3
を印刷します3
。これはいくつかの重大な驚きを引き起こす可能性があります。 defining callback functions for different buttons in a loop。 key=key
を使用してここで
は、場に出た:関数がデフォルト値としてを定義した場合、このループにkey
変数の現在の値をパラメータkey
を作成し、それに割り当てられます(したがって、あなたがする必要はありません関数を呼び出すときにパラメータを渡します)。関数は、後に呼び出されたときにそのkey
paremeterの値は、関数の範囲内で同じとどまります:
functions = []
for key in [1,2,3]:
f = lambda key=key: key
functions.append(f)
これは予想されるように、1
、2
、および3
を出力します。他の人が指摘しているように、このパラメータを別の名前にすると、これを混乱を避けることができます。 f = lambda param=key: param
。
「キー=キー」の最初のキーは、ラムダ関数の引数の名前です。 2番目のキーはローカル変数です。あなたの場合はforループ変数です。
したがって、各反復でローカルキー変数が定義されていると、fはこのローカルと同じデフォルトの1つの引数を受け取るラムダ関数として定義されます。したがって、print(キー)はこのデフォルト値。
編集: f()のコンテキストでは、keyはforループ変数ではなく、ローカルのf引数であることを強調する必要があります。ループ変数の値がデフォルトになります。
EDIT 2: idjawさんのコメントに気付いたばかりです。私はこれが答えだとは思わないが、これがあなたのコードを書いたはずである。
このコードは「シンプル」ではありませんが、実際には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のパターンであり、時には必要ですが、ここでは完全なナンセンスであり、この使い方から学ぶことは何もありません。
あなたはこれを持っているソースから読み続けることを再考する必要があります(残りは悪いことだと思います)。より良い例については公式のチュートリアルに固執してください...
ラムダ関数に 'key'イテレータを渡しています。実際には、正確に何が起こっているのかをもう少し明確にするために、 'lambda foo = key:print(foo)'としていたかもしれません。また、あなたの 'key'をかなり印刷するラムダがあるので' print(f()) 'は冗長で' None'と表示されます。だから、あなたは 'f()'を呼び出す必要があります。しかし、これはキーを印刷するための非常に奇妙なデザインの選択です。単純に 'print(key)'というだけではなく、 – idjaw
.whyがキーに戻ってキーを割り当てるのはなぜですか? "key = key" ....誰がそれを書いたのですか?.....コーダーが疲れていた可能性があります... lol – repzero
@repzeroキーにキーを戻していません。ラムダは単一の引数をとり、その引数は 'key'と命名されました。名前は実際には実際のイテレータ 'key'とは関係ありません。私のコメントで説明したように、 'foo = key'だったでしょう。 – idjaw