Python に三項条件演算子がない場合、他の言語構造を使用してシミュレートすることは可能ですか?
31 に答える
はい、バージョン 2.5で追加されました。式の構文は次のとおりです。
a if condition else b
最初condition
に が評価され、次に または のいずれa
かが評価され、 のブール値にb
基づいて返されます。が に評価される場合、は評価されて返されますが無視されます。それ以外の場合は、 が評価されて返されますが無視されます。condition
condition
True
a
b
b
a
condition
when is true のみa
が評価され、b
まったく評価されませんが、 when condition
is 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 つの値を切り替えるものと考えてください。'1 つの値または別の' 状況にある場合は非常に便利ですが、それ以外の場合はあまり機能しません。
ステートメントを使用する必要がある場合は、条件式の代わりに通常のif
ステートメントを使用する必要があります。
いくつかの理由から、一部の Pythonista は眉をひそめていることに注意してください。
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
ます。
公式文書:
2.5 より前のバージョンでは、次のようなトリックがあります。
[expression] and [on_true] or [on_false]
on_true
偽のブール値を持つ場合、間違った結果をもたらす可能性があります。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
残念ながら、
(falseValue, trueValue)[test]
ソリューションには短絡動作がありません。したがって、条件に関係なく と の両方falseValue
がtrueValue
評価されます。これは、最適ではないか、バグがある可能性があります (つまり、メソッドとメソッドの両方trueValue
であり、falseValue
副作用がある可能性があります)。
これに対する1つの解決策は
(lambda: falseValue, lambda: trueValue)[test]()
(勝者がわかるまで実行が遅れます;))、しかし、呼び出し可能なオブジェクトと呼び出し不可能なオブジェクトの間に矛盾が生じます。また、プロパティを使用する場合は解決しません。
そして、話は続きます-言及された3つのソリューションから選択することは、短絡機能を持ち、少なくともPython 2.5(私見、もう問題ではありません)を使用することと、「trueValue
-evaluates-to-false」になりにくいこととの間のトレードオフです。エラー。
さまざまなプログラミング言語での三項演算子
ここでは、いくつかのプログラミング言語間の三項演算子の重要な違いをいくつか示してみました。
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 では三項演算子は実装されていませんが、シミュレートすることは可能です。
cond and on_true or on_false
ただし、潜在的な問題があり、 if がにcond
評価されTrue
、on_true
評価がFalse
thenon_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 バージョンと互換性があります。
よく見かけるかもしれません
cond and on_true or on_false
しかし、これは on_true == 0 の場合に問題を引き起こします
>>> x = 0
>>> print x == 0 and 0 or 1
1
>>> x = 1
>>> print x == 0 and 0 or 1
1
通常の三項演算子でこの結果が期待される場所:
>>> x = 0
>>> print 0 if x == 0 else 1
0
>>> x = 1
>>> print 0 if x == 0 else 1
1
Python には三項条件演算子がありますか?
はい。文法ファイルから:
test: or_test ['if' or_test 'else' test] | lambdef
関心のある部分は次のとおりです。
or_test ['if' or_test 'else' test]
したがって、三項条件演算は次の形式になります。
expression1 if expression2 else expression3
expression3
遅延評価されます (つまりexpression2
、ブール値のコンテキストで false の場合にのみ評価されます)。また、再帰的な定義により、それらを無期限に連鎖させることができます (ただし、スタイルが悪いと見なされる場合があります)。
expression1 if expression2 else expression3 if expression4 else expression5 # and so on
使用上の注意:
if
everyの後に . を付ける必要があることに注意してくださいelse
。リスト内包表記とジェネレーター式を学んでいる人は、これを学ぶのが難しいと感じるかもしれません.Pythonはelseの3番目の式を期待しているので、以下はうまくいきません:
[expression1 if expression2 for element in iterable]
# ^-- need an else here
を発生させSyntaxError: invalid syntax
ます。したがって、上記は不完全なロジック (おそらく、ユーザーは false 条件でノーオペレーションを予期する) であるか、expression2 をフィルターとして使用することを意図している可能性があります。以下は正当な Python であることに注意してください。
[expression1 for element in iterable if expression2]
expression2
リスト内包表記のフィルターとして機能し、三項条件演算子ではありません。
より狭いケースの代替構文:
次のように書くと、少し面倒に感じるかもしれません。
expression1 if expression1 else expression2
expression1
上記の使用法では 2 回評価する必要があります。単なるローカル変数の場合、冗長性が制限される可能性があります。ただし、このユースケースの一般的でパフォーマンスの高い Pythonic イディオムは、or
のショートカット動作を使用することです。
expression1 or expression2
これは意味論的に同等です。一部のスタイルガイドでは、明確さを理由にこの使用法を制限する場合があることに注意してください。非常に小さな構文に多くの意味が詰め込まれています。
すでに答えたように、はい、Python には三項演算子があります。
<expression 1> if <condition> else <expression 2>
多くの場合<expression 1>
、評価されたブール値としても使用され<condition>
ます。次に、短絡評価を使用できます。
a = 0
b = 1
# Instead of this:
x = a if a else b
# Evaluates as 'a if bool(a) else b'
# You could use short-circuit evaluation:
x = a or b
短絡評価の大きな利点の 1 つは、2 つ以上の式を連鎖できることです。
x = a or b or c or d or e
関数を操作する場合、詳細はさらに異なります。
# Evaluating functions:
def foo(x):
print('foo executed')
return x
def bar(y):
print('bar executed')
return y
def blubb(z):
print('blubb executed')
return z
# Ternary Operator expression 1 equals to False
print(foo(0) if foo(0) else bar(1))
''' foo and bar are executed once
foo executed
bar executed
1
'''
# Ternary Operator expression 1 equals to True
print(foo(2) if foo(2) else bar(3))
''' foo is executed twice!
foo executed
foo executed
2
'''
# Short-circuit evaluation second equals to True
print(foo(0) or bar(1) or blubb(2))
''' blubb is not executed
foo executed
bar executed
1
'''
# Short-circuit evaluation third equals to True
print(foo(0) or bar(0) or blubb(2))
'''
foo executed
bar executed
blubb executed
2
'''
# Short-circuit evaluation all equal to False
print(foo(0) or bar(0) or blubb(0))
''' Result is 0 (from blubb(0)) because no value equals to True
foo executed
bar executed
blubb executed
0
'''
PS: もちろん、短絡評価は 3 項演算子ではありませんが、短絡で十分な場合は 3 項演算子がよく使用されます。可読性が高く、連鎖することができます。
答えというよりはヒントです (明白なことを 100 回繰り返す必要はありません) が、そのような構造でワンライナー ショートカットとして使用することがあります。
if conditionX:
print('yes')
else:
print('nah')
、次のようになります。
print('yes') if conditionX else print('nah')
一部の (多くの :) 人はそれを非 Pythonic として眉をひそめるかもしれません (Ruby っぽい :) でも、私は個人的にはより自然だと思います。
はい、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")
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]
>>>
or
Python では、代替割り当てに簡単に使用できます。
>>> a = li1 or li2
>>>
>>> a
[1, 2, 3]
>>>
上記はそれ以来機能li1
しNone
、インタープリターはそれを論理式で False として扱います。次に、インタープリターは次に進み、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 は構文が豊富な言語であり、初心者にはすぐにはわからない慣用的なトリックがたくさんあります。しかし、基礎となるシステムの仕組みを学び、理解すればするほど、その価値が高くなります。
物事を行うPythonicの方法:
"true" if var else "false"
しかし、三項条件を実行する別の方法も常に存在します。
"true" and var or "false"
はい、ありますが、C 構文に似たプログラミング言語 (つまり、condition ? value_if_true : value_if_false
Python では、次のようになります。value_if_true if condition else value_if_false
例:even_or_odd = "even" if x % 2 == 0 else "odd"