1

これらの2つのスニペットを考えると:

def sex (code):
    return {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code]

sex = lambda code: {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code]

実際の違いは何ですか?彼らは異なる行動をしていますか?

そして何よりも:一方が他方よりも好ましいのでしょうか?

このフォーラムでの私の回答の1つ(python3-検索について学習しているため、この非常に単純な例は正しく機能しません)は、両方の可能性を提供し、別のユーザーによって切り捨てられ(「改訂」)、ラムダ用語が削除されたためです。改訂の理由は、最後のオプション(ラムダ式)が関数定義よりも悪いためです。これは私に不思議に思いました:

ラムダ式が関数定義よりも悪いのはなぜですか?特にこのような単純なもの。

4

6 に答える 6

7

defラムダと同じものを返すaの間に機能的な違いはありません。それらはまったく同じであり、同じバイトコードを持っています。

>>> def sex (code):
...     return {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code]
>>> sex2 = lambda code: {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code]
>>> sex.__code__.co_code == sex2.__code__.co_code
True

関数のどちらの書き方も、一般的な意味で「悪い」と言うのは間違っていると思います。ただし、あなたの例では、defバージョンの方が優れています。その理由は、一般にラムダの目的は、式内に短い無名関数を簡潔に記述することであるためです。を行うことに本当の意味はありませんname = lambda: ...。すぐに名前を付ける場合は、無名関数を定義する理由はありません。

ラムダのポイントはsomeFuncRequiringCallback(lambda x: x+1)、関数に名前を付けたり、この状況以外の目的で使用したりしたくない場合に実行できることです。複数のコンテキストで関数を使用する場合は、通常ので関数を定義するだけですdef

于 2012-12-13T05:15:40.023 に答える
3

BrenBarnの優れた回答で提供されている情報に加えて、常にdefoverを使用することを主張する多くのPythonプログラマーがいるlambdaので、その理由を説明しようと思います。

基本的には、PythonのZenから次の行になります。

それを行うための明白な方法は1つ、できれば1つだけでなければなりません。

これは、この問題に関するGuido van Rossumの投稿で参照されています(GuidoはPythonの作成者です)。

なぜラムダを落とすのですか?ほとんどのPythonユーザーはLispやSchemeに慣れていないため、名前がわかりにくいです。また、ラムダは入れ子関数ではできないことを実行できるという誤解が広まっています。LauraCreightonのAha!-erlebnisを彼女に示した後も、違いはありませんでした。より良い名前でも、2つの選択肢を並べて使用するには、プログラマーが自分のプログラムに関係のない選択をすることを考える必要があると思います。選択の余地がないため、思考プロセスが合理化されます。また、map()、filter()、reduce()がなくなると、非常に短いローカル関数を実際に作成する必要がある場所はそれほど多くありません。Tkinterのコールバックが思い浮かびますが、多くの場合、コールバックは何らかの状態保持オブジェクトのメソッドである必要があります(おもちゃのプログラムは例外です)。

于 2012-12-13T05:31:52.183 に答える
3

それらは同じです、分解されたpythonバイトコードを確認してください

>>> def sex1 (code):
    return {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code]

>>> sex2 = lambda code: {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code]
>>> dis.dis(sex1)
  2           0 BUILD_MAP                3
              3 LOAD_CONST               1 ('masculino')
              6 LOAD_CONST               2 ('m')
              9 STORE_MAP           
             10 LOAD_CONST               3 ('femenino')
             13 LOAD_CONST               4 ('f')
             16 STORE_MAP           
             17 LOAD_CONST               5 ('ignorado')
             20 LOAD_CONST               6 ('')
             23 STORE_MAP           
             24 LOAD_FAST                0 (code)
             27 BINARY_SUBSCR       
             28 RETURN_VALUE        
>>> dis.dis(sex2)
  1           0 BUILD_MAP                3
              3 LOAD_CONST               1 ('masculino')
              6 LOAD_CONST               2 ('m')
              9 STORE_MAP           
             10 LOAD_CONST               3 ('femenino')
             13 LOAD_CONST               4 ('f')
             16 STORE_MAP           
             17 LOAD_CONST               5 ('ignorado')
             20 LOAD_CONST               6 ('')
             23 STORE_MAP           
             24 LOAD_FAST                0 (code)
             27 BINARY_SUBSCR       
             28 RETURN_VALUE    

どちらも同じタイプです

>>> type(sex1)
<type 'function'>
>>> type(sex2)
<type 'function'>
于 2012-12-13T05:54:54.937 に答える
0

単純なラムダは、ネストされた関数よりも必ずしも悪いわけではありません(そして、これら2つの例の間に違いはありませんが、構文です)が、この特定のケースはさらに単純になる可能性があります。

sex = {'m': 'masculino', 'f': 'femenino', '': 'ignorado'}

次に、を使用しますsex.__getitem__

于 2012-12-13T05:15:59.533 に答える
0

これらの動作は同じですが、主な違いは、ラムダは式であるため、ステートメントを含めることができないことです。ラムダは、適切に使用されていれば、関数定義よりも必ずしも悪いわけではありません。ただし、コードを読み取ることが事実上不可能になったとしても、1行の関数を作成するために使用されることがよくあります。たとえば、次のことを考慮してください。

sortfilter = lambda a, b, c: sorted(filter(lambda i: i % 2, (i for i in a if i in b)), key=lambda v: c.get(v, v)))

1行のラムダで書くことは可能ですが、本当に悪い考えです!

于 2012-12-13T05:33:34.870 に答える
0

それは物事を区別するのに役立ちます。関数を定義する場合はdefから始めますが、その関数内では通常ラムダを使用します。

英語で書くのと同じ概念です。引用符が引用符を引用している場合は、ネストされた引用符の外観を変更する必要があります。これは括弧にも当てはまります。

于 2015-05-21T10:32:07.503 に答える