web-dev-qa-db-ja.com

引数にアンダースコア付きのPythonラムダ?

次のコードは何をしますか?

a = lambda _:True

インタラクティブプロンプトで読んでテストした結果から、常にTrueを返す関数のようです。

これを正しく理解していますか?アンダースコア(_)が使用された理由を理解したいと思っています。

69
laycat

_は変数名です。それを試してみてください。 (通常、この変数名は無視される変数の名前です。いわばプレースホルダーです。)

Python:

>>> l = lambda _: True
>>> l()
<lambda>() missing 1 required positional argument: '_'

>>> l("foo")
True

したがって、このラムダ1つの引数が必要です。常にTrueを返すラムダ引数なしが必要な場合は、次のようにします。

>>> m = lambda: True
>>> m()
True
113
user1907906

アンダースコアは、未使用の変数に名前を付けるPython規則です(たとえば、静的分析ツールは、未使用の変数としてそれを報告しません)。あなたの場合、ラムダ引数は使用されませんが、作成されるオブジェクトは単一引数関数であり、常にTrueを返します。したがって、ラムダは数学の 定数関数 に多少似ています。

6

それは関係なくTrueを返す関数のようです。

はい、Trueを返す関数(またはラムダ)です。この場合、通常は無視される変数のプレースホルダーである アンダースコア は不要です。

ユースケースそのような関数(ほとんど何もしません):

dd = collections.defaultdict(lambda: True)

defaultdict の引数として使用する場合、Trueを一般的なデフォルト値として使用できます。

6
miku

ラムダは関数を意味します。上記の文は次の記述と同じです

def f(_):
    return True

ラムダの場合、変数が存在する必要があります。したがって、_という変数を渡します(同様に、xy ..を渡すことができます)

4
hyades

アンダースコア_は有効な識別子であり、ここでは変数名として使用されます。関数に渡された引数に対して常にTrueを返します。

>>>a('123') 
True
3
haccks

問題のコード行は次のとおりです。

a = lambda _:True

1つの入力パラメーターを持つ関数を作成します:_。アンダースコアは変数名のかなり奇妙な選択ですが、単なる変数名です。ラムダ関数を使用しない場合でも、_はどこでも使用できます。たとえば、...の代わりに.

my_var = 5
print(my_var)

あなたは書くことができます:

_ = 5
print(_)

ただし、xinputのようなものではなく、_がパラメーター名として使用された理由がありました。これについてはすぐに説明します。

最初に、ラムダキーワードがdefに似ていますが、構文が異なる関数を構築することを知る必要があります。ラムダ関数a = lambda _:Trueの定義は、次の記述に似ています。

def a(_):
    return True

入力パラメーター_を持つaという名前の関数を作成し、Trueを返します。アンダースコアの代わりにxを使用して、簡単にa = lambda x:Trueと書くこともできます。ただし、その変数を使用するつもりがない場合は、_を変数名として使用するという規則があります。以下を考慮してください。

for _ in range(1, 11):
    print('pear')

ループインデックスは、ループ本体の内部では使用されないことに注意してください。指定した回数だけループを実行したいだけです。 winklerrrが書いたように、「変数名_は[...]のように「スローアウェイ変数」であり、役に立たない単なるプレースホルダーです。」

同様に、「a = lambda x:True」では、入力パラメーターは関数の本体内で使用されません。入力引数が存在する限り、入力引数が何であるかは実際には関係ありません。そのラムダ関数の作成者は、変数が使用されないことを示すために、xのようなものの代わりに_を作成しました。

ラムダdoesには引数があることに注意してください。だから、書く

a()、エラーが発生します。

引数なしのラムダが必要な場合は、次のように記述します。

 bar = lambda: True

引数なしでbar()を呼び出すと、問題なく動作します。引数をとらないラムダは、常に同じ値を返す必要はありません。

import random
process_fruit = lambda : random.random()

上記のラムダ関数は、常に同じ定数を返すものよりも複雑です。

プログラマがlambdaの代わりにdefキーワードを使用する場合がある理由の1つは、特に短く単純な関数のためです。 lambdaの定義は、通常、すべてを1行に収めることができますが、defステートメントで同じことを行うのは難しいことに注意してください。関数が再び使用されないときにlambda sfの代わりにdefを使用するもう1つの理由。後で関数を再度呼び出したくない場合は、関数に名前を付ける必要はありません。たとえば、次のコードを検討してください。

def apply_to_each(transform、in_container):out_container = idxのlist()、enumerate(container、0)のアイテム:out_container [idx] = transform(item)return out_container

次に、次の呼び出しを行います。

squares  = apply_to_each(lambda x: x**2 range(0, 101))

lambda x: x**2にはラベルが与えられていないことに注意してください。これは、おそらく後で再び呼び出すことはないからです。一時的に必要なもので、短くて単純なものでした。

ラムダ関数に名前を付ける必要がないという事実は、ラムダ関数を記述するための別の名前のソースです:「匿名関数」。

また、ラムダステートメントは、作成する関数への参照を返すという点で、関数呼び出しに似ていることに注意してください。以下は違法です:

apply_to_each(def foo(x): x**2 ,  range(0, 101))

一方、apply_to_each(lambda x: x**2 range(0, 101))は問題ありません。

したがって、短くて甘いものが必要で、おそらく後で再び使用したくない場合は、長い変数名の代わりにlambda_の代わりにdefを使用します。

2
IdleCustard