Pythonに3項条件演算子がない場合、他の言語構造を使用して1つをシミュレートすることは可能ですか?
case [...] { when ... then ...} [ else ... ] end
同様の効果がありますが、3値ではありません。
Pythonに3項条件演算子がない場合、他の言語構造を使用して1つをシミュレートすることは可能ですか?
case [...] { when ... then ...} [ else ... ] end
同様の効果がありますが、3値ではありません。
回答:
はい、バージョン2.5で追加されました。式の構文は次のとおりです。
a if condition else b
最初condition
に評価され、次にa
またはb
のブール値のいずれかに基づいて評価または返されますcondition
。場合はcondition
評価するにTrue
は、a
評価され、返されるがb
無視されるか、あるいは時にb
評価され、返されるがa
、無視されます。
これcondition
は、true a
が評価されるだけで評価されないので短絡を許可しますb
が、condition
false b
が評価されるだけa
でまったく評価されないためです。
例えば:
>>> 'true' if True else 'false'
'true'
>>> 'true' if False else 'false'
'false'
条件文は式ではなく、ステートメントであることに注意してください。つまり、条件式内では代入ステートメントpass
やその他のステートメントを使用できません。
>>> pass if False else x = 3
File "<stdin>", line 1
pass if False else x = 3
^
SyntaxError: invalid syntax
ただし、条件式を使用して、次のように変数を割り当てることができます。
x = a if True else b
条件式は、2つの値を切り替えるものと考えてください。これは、「ある値か別の値か」の状況にあるときに非常に役立ちますが、それ以外のことはほとんど行いません。
ステートメントを使用する必要がある場合は、条件式ではなく通常のif
ステートメントを使用する必要があります。
いくつかの理由により、一部のPythonistasには不満を抱いていることに注意してください。
condition ? a : b
他の多くの言語(C、C ++、Go、Perl、Ruby、Java、Javascriptなど)の古典的な三項演算子の順序とは異なり、Pythonの「意外な」動作で使用されます(引数の順序が逆になる場合があります)。if
」は本当に便利で、スクリプトをより簡潔にすることができますが、実際にはコードが複雑になります)順序を思い出せない場合は、声に出して読んだときに、(ほとんど)意味がわかります。たとえば、x = 4 if b > 8 else 9
は読み上げられx will be 4 if b is greater than 8 otherwise 9
ます。
公式ドキュメント:
f(x) = |x| = x if x > 0 else -x
、数学者にとっては非常に自然に聞こえます。ほとんどの場合、Aと同じように理解できますが、Cの場合はBを実行する必要があります...
z = 3 + x if x < y else y
。との場合x=2
、y=1
4が得られると期待できますが、実際にz = 3 + (x if x > y else y)
は1 が得られます。これが正しい使用方法です。
z = 3 + x if x < y else 3 + y
)か、条件をグループ化する(z = 3 + (x if x < y else y)
またはz = (x if x < y else y) + 3
)
タプルにインデックスを付けることができます:
(falseValue, trueValue)[test]
test
TrueまたはFalseを返す必要があります。
常に次のように実装する方が安全な場合があります。
(falseValue, trueValue)[test == True]
または、組み込みを使用しbool()
てブール値を保証できます。
(falseValue, trueValue)[bool(<expression>)]
(lambda: print("a"), lambda: print("b"))[test==true]()
[]
s 内には任意の式を使用できることに注意してください。また、安全のために、と書いて真実性を明示的にテストできます[bool(<expression>)]
。このbool()
関数はv2.2.1以降で使用されています。
True
とFalse
:キーとして {True:trueValue, False:falseValue}[test]
私は、これは任意のあまり効率的であるかどうかわからないが、それは全体の少なくとも回避でありません「エレガント」対「醜い」議論。intではなくbooleanを扱っていることは明白です。
2.5より前のバージョンの場合、トリックがあります。
[expression] and [on_true] or [on_false]
on_true
ブール値がfalseの場合、誤った結果をもたらす可能性があります。1
それは式を左から右に評価する利点がありますが、私の意見ではより明確です。
<expression 1> if <condition> else <expression 2>
a = 1
b = 2
1 if a > b else -1
# Output is -1
1 if a > b else -1 if a < b else 0
# Output is -1
Pythonの条件式の演算子は、2006年にPython拡張提案308の一部として追加されました。その形式は一般的な?:
演算子とは異なり、次のとおりです。
<expression1> if <condition> else <expression2>
これは次と同等です:
if <condition>: <expression1> else: <expression2>
次に例を示します。
result = x if a > b else y
使用できる別の構文(2.5より前のバージョンと互換性があります):
result = (lambda:y, lambda:x)[a > b]()
オペランドが遅延評価される場所ます。
別の方法は、タプルにインデックスを付けることです(これは、他のほとんどの言語の条件演算子と一貫性がありません)。
result = (y, x)[a > b]
または明示的に構築された辞書:
result = {True: x, False: y}[a > b]
別の(信頼性は低い)が、より単純な方法は、and
およびor
演算子を使用することです。
result = (a > b) and x or y
しかし、これはうまくいかないx
でしょうFalse
。
可能な回避策は、次のようにリストまたはタプルを作成x
してy
リストを作成することです。
result = ((a > b) and [x] or [y])[0]
または:
result = ((a > b) and (x,) or (y,))[0]
辞書を使用している場合は、3項条件を使用する代わりに、を利用できます。get(key, default)
次に例を示します。
shell = os.environ.get('SHELL', "/bin/sh")
result = {1: x, 0: y}[a > b]
別の可能な変形である(True
そしてFalse
実際の値を持つ整数である1
と0
)
残念ながら、
(falseValue, trueValue)[test]
ソリューションには短絡動作がありません。したがって、両方falseValue
とtrueValue
関係なく、条件の評価を行っています。これは最適とは言えない、またはバグが多い(つまり、両方trueValue
とfalseValue
方法であると副作用を持つことができます)。
これに対する1つの解決策は
(lambda: falseValue, lambda: trueValue)[test]()
(実行は勝者がわかるまで延期されます;))、しかし、それは呼び出し可能オブジェクトと呼び出し不可能オブジェクトの間に不整合をもたらします。また、プロパティを使用する場合も解決されません。
そして、話は続きます-言及された3つの解決策から選択することは、短絡機能を備えること、少なくともЗython2.5を使用すること(IMHOはもはや問題ではない)、および「trueValue
-evaluates-to-false」エラーを起こしにくいことの間のトレードオフです。 。
if else if
。
ここでternary operator
は、いくつかのプログラミング言語の重要な違いをいくつか示します。
JavaScriptの三項演算子
var a = true ? 1 : 0;
# 1
var b = false ? 1 : 0;
# 0
Rubyの三項演算子
a = true ? 1 : 0
# 1
b = false ? 1 : 0
# 0
Scalaの三項演算子
val a = true ? 1 | 0
# 1
val b = false ? 1 | 0
# 0
Rプログラミングの三項演算子
a <- if (TRUE) 1 else 0
# 1
b <- if (FALSE) 1 else 0
# 0
Pythonの三項演算子
a = 1 if True else 0
# 1
b = 1 if False else 0
# 0
Python 2.5以降の場合、特定の構文があります。
[on_true] if [cond] else [on_false]
古いPythonでは、3項演算子は実装されていませんが、シミュレーションすることは可能です。
cond and on_true or on_false
けれどもが、あれば潜在的な問題があり、cond
と評価するTrue
とon_true
と評価されFalse
、その後は、on_false
代わりに返されますon_true
。この動作が必要な場合はメソッドで問題ありませんが、それ以外の場合はこれを使用します。
{True: on_true, False: on_false}[cond is True] # is True, not == True
これは次のようにラップできます。
def q(cond, on_true, on_false)
return {True: on_true, False: on_false}[cond is True]
このように使用しました:
q(cond, on_true, on_false)
すべてのPythonバージョンと互換性があります。
q("blob", on_true, on_false)
戻りますon_false
が、on_true if cond else on_false
戻りますon_true
。この問題を回避するには、交換することであるcond
とcond is not None
それが完璧なソリューションではないが、これらのケースで。
bool(cond)
代わりにしないのはなぜcond is True
ですか?前者はの真偽をcond
チェックし、後者はTrue
オブジェクトとのポインタの等価性をチェックします。@AndrewCecilによって強調されているように、"blob"
真実ですがそれはis not True
。
[on_false, on_True][cond is True]
、式を短くすることもできます。
Pythonには三項条件演算子がありますか?
はい。文法ファイルから:
test: or_test ['if' or_test 'else' test] | lambdef
関心のある部分は次のとおりです。
or_test ['if' or_test 'else' test]
したがって、3項条件演算は次の形式になります。
expression1 if expression2 else expression3
expression3
遅延評価されます(つまりexpression2
、ブールコンテキストでがfalseの場合にのみ評価されます)。また、再帰的な定義のため、それらを無制限にチェーンすることができます(ただし、スタイルが悪いと見なされる場合があります)。
expression1 if expression2 else expression3 if expression4 else expression5 # and so on
注意してください if
後にelse
。リストの内包表記とジェネレータ式を学習している人は、これを学ぶのは難しいレッスンであると感じるかもしれません-Pythonはelseの3番目の式を期待しているため、以下は機能しません。
[expression1 if expression2 for element in iterable]
# ^-- need an else here
それは SyntaxError: invalid syntax
ます。したがって、上記は不完全なロジック(おそらく、ユーザーがfalse条件で何もしないことを期待する)であるか、式2をフィルターとして使用することを意図している可能性があります-次は正当なPythonであることに注意してください。
[expression1 for element in iterable if expression2]
expression2
リストの内包のためのフィルタとして動作し、あるではありません 3項条件演算子で。
次のように書くのは少し辛いかもしれません:
expression1 if expression1 else expression2
expression1
上記の使用法で2回評価する必要があります。単にローカル変数の場合、冗長性を制限できます。ただし、このユースケースで一般的でパフォーマンスの高いPythonicイディオムは、or
のショートカット動作を使用することです。
expression1 or expression2
これはセマンティクスで同等です。一部のスタイルガイドでは、わかりやすくするためにこの使用法を制限している場合があることに注意してください。非常に小さな構文に多くの意味が詰め込まれています。
expression1 or expression2
expression1 || expression2
javascript と同様に、同じ欠点と利点がある
expressionN
すべてのインスタンスでメタ構文を使用することには一貫性がありますが、条件付きテスト式と2つの結果式を区別するネーミングを使用すると理解しやすいかもしれません。例えば、result1 if condition else result2
。これは、ネスト(別名チェーン)の場合に特に顕著ですresult1 if condition1 else result2 if condition2 else result3
。この方法でどれほど読みやすくなるか見てください。
Pythonの三項演算子のシミュレーション。
例えば
a, b, x, y = 1, 2, 'a greather than b', 'b greater than a'
result = (lambda:y, lambda:x)[a > b]()
出力:
'b greater than a'
result = (y, x)[a < b]
を使用lambda
するのですか?
三項条件演算子を使用すると、複数行のif-elseを置き換えて単一行で条件をテストできるため、コードがコンパクトになります。
[on_true] if [式] else [on_false]
# Program to demonstrate conditional operator
a, b = 10, 20
# Copy value of a in min if a < b else copy b
min = a if a < b else b
print(min) # Output: 10
# Python program to demonstrate ternary operator
a, b = 10, 20
# Use tuple for selecting an item
print( (b, a) [a < b] )
# Use Dictionary for selecting an item
print({True: a, False: b} [a < b])
# lamda is more efficient than above two methods
# because in lambda we are assure that
# only one expression will be evaluated unlike in
# tuple and Dictionary
print((lambda: b, lambda: a)[a < b]()) # in output you should see three 10
# Python program to demonstrate nested ternary operator
a, b = 10, 20
print ("Both a and b are equal" if a == b else "a is greater than b"
if a > b else "b is greater than a")
上記のアプローチは次のように書くことができます:
# Python program to demonstrate nested ternary operator
a, b = 10, 20
if a != b:
if a > b:
print("a is greater than b")
else:
print("b is greater than a")
else:
print("Both a and b are equal")
# Output: b is greater than a
if-else
は実際には三項演算子の書き換えではなく、aとbの選択値に対して異なる出力を生成します(特に、1つが奇妙な__ne__
メソッドを実装するタイプの場合)。
あなたはこれを行うことができます :-
[condition] and [expression_1] or [expression_2] ;
例:-
print(number%2 and "odd" or "even")
これは、数値が奇数の場合は「奇数」、偶数の場合は「偶数」を出力します。
注意 :- -0、None、False、emptylist、emptyStringはFalseとして評価されます。また、0以外のデータはすべてTrueと評価されます。
条件[condition]が "True"になると、expression_1は評価されますが、expression_2は評価されません。0(ゼロ)で何かを「かつ」すると、結果は常に面倒になります。以下のステートメントでは、
0 and exp
「and」と0は常にゼロに評価され、式を評価する必要がないため、式expはまったく評価されません。これは、コンパイラ自体がすべての言語で機能する方法です。
に
1 or exp
式expは、「or」が1であるため常に評価されないため、結果はいずれにしても1になるため、式expを評価する必要はありません。(コンパイラ最適化メソッド)。
しかしの場合
True and exp1 or exp2
2番目の式exp2は評価されません True and exp1
、exp1がfalseではないときにTrueにません。
同様に
False and exp1 or exp2
式exp1は、Falseが0を書き込むことと同等であり、0で「and」を実行するとそれ自体が0になるため、評価されません。ただし、「or」が使用されるため、exp1の後では、「or」の後に式exp2が評価されます。
注意:-「or」と「and」を使用したこの種の分岐は、expression_1がFalse(または0またはNoneまたはemptylist []またはemptystring ''。)の真理値を持たない場合にのみ使用できます。 Falseの場合、exp_1とexp_2の間に「または」が存在するため、expression_2が評価されます。
exp_1とexp_2の真理値が何であるかに関係なく、すべてのケースで引き続き機能させる場合は、次のようにします。
[condition] and ([expression_1] or 1) or [expression_2] ;
x = [condition] and ([expression_1] or 1) or [expression_2]
やexpression_1
falseと評価、x
となります1
、ではありませんexpression_1
。受け入れられた答えを使用してください。
答えというよりはヒントです(100分の時間の間、明白なことを繰り返す必要はありません)が、そのような構成体でワンライナーショートカットとして使用することがあります。
if conditionX:
print('yes')
else:
print('nah')
は、次のようになります。
print('yes') if conditionX else print('nah')
一部の(多くの:)はunpythonic(さえ、ルビーっぽい:)として不快に思うかもしれませんが、個人的にはより自然に感じます。つまり、通常の表現方法に加えて、コードの大きなブロックで少し視覚的に魅力的です。
print( 'yes' if conditionX else 'nah' )
はあなたの答えよりも好きです。:-)
print()
両方の場合にしたい場合-そしてそれがもう少しpythonicに見える場合、私は認めざるを得ません:)しかし、式/関数が同じでない場合-のようにprint('yes') if conditionX else True
- print()
唯一の真実を取得するにはconditionX
print('yes') if conditionX else print('nah')
を補足すると、Python2でSyntaxErrorが発生することを回避する別の理由があります。
print "yes"
であるのに対し、Python 3ではprintが関数であるためprint("yes")
です。これは、ステートメントとして使用するか、より良い方法で解決できますfrom future import print_function
。
Pythonの条件式の代替手段の1つ
"yes" if boolean else "no"
以下は:
{True:"yes", False:"no"}[boolean]
これは次の素晴らしい拡張子を持っています:
{True:"yes", False:"no", None:"maybe"}[boolean_or_none]
最も短い代替案が残っています:
("no", "yes")[boolean]
に代わるものはありません
yes() if boolean else no()
yes()
and の評価を避けたい場合はno()
、
(no(), yes())[boolean] # bad
両方no()
とyes()
評価されます。
から派生した多くのプログラミング言語には、C
通常、3項条件演算子の次の構文があります。
<condition> ? <expression1> : <expression2>
まず、
Python
Bの enevolentのDの ictator FまたはLのそれが使用されていない人々のために理解することは非常に難しいので、IFEは、(私はもちろんのグイド・ヴァンロッサムを意味する)、(非Python的スタイルとして)それを拒否しC
た言語。また、コロン記号は:
すでにで多くの用途がありPython
ます。PEP 308が承認された後、Python
ついに独自のショートカット条件式(現在使用しているもの)を受け取りました。
<expression1> if <condition> else <expression2>
したがって、最初に条件を評価します。が返された場合True
、expression1が評価されて結果が返されます。それ以外の場合は、expression2が評価されます。遅延評価のため仕組み 1つの式のみが実行されます。
次に例を示します(条件は左から右に評価されます)。
pressure = 10
print('High' if pressure < 20 else 'Critical')
# Result is 'High'
三項演算子は直列にチェーンできます:
pressure = 5
print('Normal' if pressure < 10 else 'High' if pressure < 20 else 'Critical')
# Result is 'Normal'
次のものは前のものと同じです:
pressure = 5
if pressure < 20:
if pressure < 10:
print('Normal')
else:
print('High')
else:
print('Critical')
# Result is 'Normal'
お役に立てれば。
すでに答えたように、はい、Pythonに三項演算子があります。
<expression 1> if <condition> else <expression 2>
追加情報:
<expression 1>
条件である場合、短絡評価を使用できます。
a = True
b = False
# Instead of this:
x = a if a else b
# You could use Short-cirquit evaluation:
x = a or b
PS:もちろん、短絡評価は三項演算子ではありませんが、多くの場合、短絡で十分な場合に三項が使用されます。
short-circuit
評価に賛成票を投じます。
はい、pythonには三項演算子があります。これは同じことを示す構文とコード例です:)
#[On true] if [expression] else[On false]
# if the expression evaluates to true then it will pass On true otherwise On false
a= input("Enter the First Number ")
b= input("Enter the Second Number ")
print("A is Bigger") if a>b else print("B is Bigger")
print
Python2でSyntaxErrorが発生するため、これは本当に良い選択ではありません。
Pythonには割り当て用の3項形式があります。ただし、人々が知っておくべきもっと短い形式があるかもしれません。
条件に応じて変数に値を割り当てる必要があるのは非常に一般的です。
>>> li1 = None
>>> li2 = [1, 2, 3]
>>>
>>> if li1:
... a = li1
... else:
... a = li2
...
>>> a
[1, 2, 3]
^これは、そのような割り当てを行うための長い形式です。
以下は三項形式です。しかし、これは最も簡潔な方法ではありません-最後の例を参照してください。
>>> a = li1 if li1 else li2
>>>
>>> a
[1, 2, 3]
>>>
Pythonを使用するとor
、単に代替の割り当てに使用できます。
>>> a = li1 or li2
>>>
>>> a
[1, 2, 3]
>>>
上記li1
はNone
そのままで機能し、interpは論理式でそれをFalseとして扱います。次に、interpは次に進み、2番目の式を評価します。None
空のリストではなく、空のリストでもないため、aに割り当てられます。
これは空のリストでも機能します。たとえば、a
アイテムがあるリストを割り当てたい場合などです。
>>> li1 = []
>>> li2 = [1, 2, 3]
>>>
>>> a = li1 or li2
>>>
>>> a
[1, 2, 3]
>>>
これを知っていれば、遭遇したときはいつでも、そのような割り当てを簡単に行うことができます。これは文字列や他のイテラブルでも機能します。a
空でない文字列を割り当てることができます。
>>> s1 = ''
>>> s2 = 'hello world'
>>>
>>> a = s1 or s2
>>>
>>> a
'hello world'
>>>
私はいつもCの3値構文が好きでしたが、Pythonはそれをさらに一歩進めました!
これは、すべての開発者にはすぐにはわからないメカニズムに依存しているため、これはスタイルの選択としては適切でないと言う人もいるかもしれません。私はその見方に個人的に反対します。Pythonは構文が豊富な言語であり、イブラーにはすぐにはわからない多くの慣用的なトリックがあります。しかし、基礎となるシステムの仕組みを学び、理解すればするほど、それを高く評価するようになります。
その他の答えは、Pythonの三項演算子について正しく説明しています。三項演算子がよく使用されるが、より良いイディオムがあるシナリオに言及することで補足したいと思います。これは、デフォルト値を使用するシナリオです。
option_value
設定されていない場合、デフォルト値で使用したいとします。
run_algorithm(option_value if option_value is not None else 10)
または単に
run_algorithm(option_value if option_value else 10)
ただし、より優れた解決策は、単に
run_algorithm(option_value or 10)
変数が定義されていて、値があるかどうかを確認したい場合は、 a or b
def test(myvar=None):
# shorter than: print myvar if myvar else "no Input"
print myvar or "no Input"
test()
test([])
test(False)
test('hello')
test(['Hello'])
test(True)
出力されます
no Input
no Input
no Input
hello
['Hello']
True
x if x else y
が、そうではありませんx if z else y
。