web-dev-qa-db-ja.com

Pythonの1行ラムダ関数の条件文?

これは以前に尋ねられた場合は申し訳ありませんが、どこにもそれを見ることができませんでした。

基本的に、ラムダ関数内のifステートメントを使用する必要があるシナリオに出くわしました。難しいのは、理想的には単一行のコードにする必要があるということです(それが可能な場合でも?)

通常、私はこれを書くでしょう:

T = 250

if (T > 200):
    rate = 200*exp(-T)
else:
    rate = 400*exp(-T)

return (rate)

しかし、私はこのように見える必要があります:

rate = lambda(T) : if (T>200): return(200*exp(-T)); else: return(400*exp(-T))

ラムダ関数の外側で意思決定を行い、各ケースに個別のラムダ関数を用意する方が簡単だと思いますが、ここではあまり適していません。ラムダ関数は配列に格納され、必要に応じてアクセスされます。各配列要素は特定の「レート」に対応するため、同じ「レート」に対して2つの別々の行があると混乱します。どんな助けも大歓迎です、またはそれが不可能な場合、他からのいくつかの確認がいいでしょう:)

56
Nathan Bush

exp1 if cond else exp2構文を使用します。

rate = lambda T: 200*exp(-T) if T>200 else 400*exp(-T)

ラムダ式ではreturnを使用しないことに注意してください。

83
shx2

これを行う正しい方法は簡単です:

def rate(T):
    if (T > 200):
        return 200*exp(-T)
    else:
        return 400*exp(-T)

ここでlambdaを使用する利点はまったくありません。 lambdaに適しているのは、匿名関数を作成し、式で(ステートメントではなく)使用できるようにすることだけです。 lambdaをすぐに変数に割り当てると、変数は匿名ではなくなり、ステートメントで使用されるため、理由もなくコードが読みにくくなります。

このように定義されたrate関数は、ラムダ関数とまったく同じ方法で配列に格納したり、渡したり、呼び出したりすることができます。これはまったく同じです(デバッグやイントロスペクトなどが少し簡単なことを除きます)。


コメントから:

関数は1行に収まる必要がありましたが、名前付き関数でできるとは思いませんでしたか?

関数が1行に収まる必要がある理由を想像することはできません。ただし、名前付き関数を使用してそれを行うことができます。インタープリターでこれを試してください:

>>> def foo(x): return x + 1

また、これらの関数は「eval」を使用して評価される文字列として保存されますが、これは通常の関数の実行方法がわかりませんでした。

繰り返しになりますが、なぜあなたがこれをしているのかについての手掛かりなしに100%確信するのは難しいですが、少なくとも99%はあなたにこの理由や悪い理由がないと確信しています。 Python関数を文字列として渡し、使用できるようにevalを呼び出したいと思うときはいつでも、実際には単にPython関数を関数として渡し、機能。

しかし、これが本当にあなたがここで必要なものであるという偶然に:execの代わりにevalを使用してください。

使用しているPythonのバージョンについては言及していません。 3.xでは、 exec 関数のシグネチャはeval関数とまったく同じです。

exec(my_function_string, my_globals, my_locals)

2.7では、 exec は関数ではなくステートメントです。ただし、3.xと同じ構文で記述できます(戻り値を何かに割り当てようとしない限り) )そしてそれは動作します。

以前の2.x(2.6より前だと思いますか?)では、代わりに次のようにしなければなりません:

exec my_function_string in my_globals, my_locals
20
abarnert

はい、ifステートメントの短縮構文を使用できます。

rate = lambda(t): (200 * exp(-t)) if t > 200 else (400 * exp(-t))

returnsでも明示的なlambdaステートメントを使用しないことに注意してください。

7
Silas Ray

ラムダで「if-then」ステートメントを使用する必要があることがわかりました。例えば:

eval_op = {
    '|'  : lambda x,y: eval(y) if (eval(x)==0) else eval(x),
    '&'  : lambda x,y: 0 if (eval(x)==0) else eval(y),
    '<'  : lambda x,y: 1 if (eval(x)<eval(y)) else 0,
    '>'  : lambda x,y: 1 if (eval(x)>eval(y)) else 0,
}
5
pkmccroskey

rate = lambda whatever...と言うときまでに、ラムダのポイントを破ったので、関数を定義するだけです。ただし、ラムダが必要な場合は、「and」と「or」を使用できます

lambda(T): (T>200) and (200*exp(-T)) or (400*exp(-T))
4
tdelaney