web-dev-qa-db-ja.com

Pythonには3項条件演算子がありますか?

Pythonに3項条件演算子がない場合、他の言語構成子を使ってシミュレートすることは可能ですか?

5163
Devoted

はい、バージョン2.5では added でした。式の構文は次のとおりです。

a if condition else b

最初にconditionが評価され、次にaまたはbのいずれか一方のみが評価され、 Booleanconditionの値に基づいて返されます。 conditionTrueと評価された場合、aは評価されて返されますがbは無視されます。それ以外の場合、bが評価されて返されたがaは無視されます。

conditionがtrueの場合はaのみが評価され、bはまったく評価されませんが、conditionがfalseの場合はbのみが評価され、aはまったく評価されないため、短絡が可能です。

例えば:

>>> 'true' if True else 'false'
'true'
>>> 'true' if False else 'false'
'false'

条件式はexpressionであり、statementではないことに注意してください。つまり、代入文やpassなどのを条件付きの中で使用することはできません。

>>> pass if False else x = 3
  File "<stdin>", line 1
    pass if False else x = 3
          ^
SyntaxError: invalid syntax

そのような場合は、条件付きの代わりに通常のif ステートメント を使用する必要があります。


いくつかの理由でいくつかのPythonistaが眉をひそめていることを覚えておいてください:

  • 引数の順番は、他の多くの言語(C、C++、Go、Perl、Ruby、Java、Javascriptなど)の古典的なcondition ? a : b三項演算子のものとは異なります。 「驚くべき」振る舞いはそれを使います(それらは引数の順序を逆にするかもしれません)。
  • それは通常の思考の流れ(最初に条件を考え、次に効果を考える)に反するので、それを「扱いにくい」と感じる人もいます。
  • 文体的な理由.

順番を思い出すのに問題がある場合は、声を出して読んだときに、(ほとんど)自分の言っていることを言っていることを忘れないでください。たとえば、x = 4 if b > 8 else 9x will be 4 if b is greater than 8 otherwise 9として読み上げられます。

公式文書 

5921
Vinko Vrsalovic

あなたはタプルにインデックスを付けることができます:

(falseValue, trueValue)[test]

testは、 True または False を返す必要があります。
常に次のように実装するほうが安全な場合があります。

(falseValue, trueValue)[test == True]

あるいは、組み込みの bool() を使用して ブール値 値を保証​​することもできます。

(falseValue, trueValue)[bool(<expression>)]
657
Landon Kuhn

2.5より前のバージョンでは、トリックがあります:

[expression] and [on_true] or [on_false]

on_true にfalseのブール値があると、間違った結果が生じる可能性があります。1
式を左から右に評価するという利点はありますが、これは私の意見では明らかです。

1. Cの「?:」三項演算子に相当するものはありますか。

271
James Brady

式1 if 条件 else 式2

>>> a = 1
>>> b = 2
>>> 1 if a > b else -1 
-1
>>> 1 if a > b else -1 if a < b else 0
-1
175

から

条件式(「三項演算子」と呼ばれることもあります)は、すべてのPython演算の中で最も低い優先順位を持ちます。

x if C else yは最初に条件を評価します。 _ c _ x ではなく)。 _ c _ がtrueの場合、 x が評価され、その値が返されます。そうでなければ、 y が評価され、その値が返されます。

条件式についての詳細は PEP 308 を参照してください。

バージョン2.5以降の新機能.

122
Michael Burr

Pythonの条件式の演算子は2006年に Python Enhancement Proposal 308 の一部として追加されました。その形式は一般的な?:演算子と異なり、それはそれです:

<expression1> if <condition> else <expression2>

これは以下と同等です。

if <condition>: <expression1> else: <expression2>

これが一例です。

result = x if a > b else y

使用できるもう1つの構文(2.5より前のバージョンと互換性があります):

result = (lambda:y, lambda:x)[a > b]()

オペランドは 遅延評価されます

もう1つの方法は、タプルを索引付けすることです(これは他のほとんどの言語の条件付き演算子と矛盾します)。

result = (y, x)[a > b]

または明示的に構築された辞書:

result = {True: x, False: y}[a > b]

別の(信頼性は低いですが)もっと簡単な方法はandor演算子を使うことです:

result = (a > b) and x or y

ただし、xFalseになる場合、これは機能しません。

考えられる回避策は、以下のようにxyのリストまたはタプルを作成することです。

result = ((a > b) and [x] or [y])[0]

または

result = ((a > b) and (x,) or (y,))[0]

もしあなたが辞書を使っていて、三項条件式を使う代わりに、 get(key, default) を利用することができます、例えば:

Shell = os.environ.get('Shell', "/bin/sh")

出典: ?:WikipediaのPythonの場合

92
kenorb

@アップ:

残念ながら、

(falseValue, trueValue)[test]

解決策は、短絡動作をしていません。したがって、falseValueとtrueValueの両方が条件に関係なく評価されます。これは、最適とは言えない、あるいはバグさえある可能性があります(つまり、trueValueとfalseValueの両方がメソッドであり、副作用がある可能性があります)。

これに対する1つの解決策は、

(lambda: falseValue, lambda: trueValue)[test]()

(勝者がわかるまで実行は遅延します;))ただし、呼び出し可能オブジェクトと呼び出し不可能オブジェクトの間に矛盾が生じます。また、プロパティを使用した場合の問題も解決されません。

3つの解決方法を選択することは、少なくともpython 2.5(IMHOはもう問題ではない)を使用することと、「trueValue-evaluate-to-false」が発生しにくいこととの間のトレードオフです。エラー.

86
gorsky

Python 2.5以降では、特定の構文があります。

[on_true] if [cond] else [on_false]

古いPythonsでは三項演算子は実装されていませんが、それをシミュレートすることは可能です。

cond and on_true or on_false

ただし、condTrueと評価され、on_trueFalseと評価されると、on_falseの代わりにon_trueが返されるという潜在的な問題があります。この振る舞いをしたいのであれば、そのメソッドはOKです。

{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バージョンと互換性があります。

54
Paolo

異なるプログラミング言語の三項演算子

ここでは、2つのプログラミング言語の間でのternary operatorの重要な違いをいくつか示します。

Javascriptの3項演算子

var a = true ? 1 : 0;
# 1
var b = false ? 1 : 0;
# 0

Rubyの三項演算子

a = true ? 1 : 0
# 1
b = false ? 1 : 0
# 0

Scalaの3項演算子

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
51
Simplans

あなたはしばしば見つけるかもしれません

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
35

絶対に、そしてそれは非常に理解しやすいです。 

general syntax : first_expression if bool_expression_is_true else second_expression

Example: x= 3 if 3 > 2 else 4 
# assigns 3 to x if the boolean expression evaluates to true or 4 if it is false
30
BattleDrum

Pythonには3項条件演算子がありますか?

はい。 文法ファイルから

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はリスト内包表記のフィルタとして働き、notは3項条件演算子です。

より狭いケースのための代替構文:

次のように書くのは多少面倒です。

expression1 if expression1 else expression2

expression1は上記の使用法で2回評価される必要があります。単純にローカル変数である場合は、冗長性が制限される可能性があります。しかし、このユースケースの一般的で高性能なPythonicイディオムは、orのショートカット動作を使うことです。

expression1 or expression2

これは意味的に等価です。明快さの理由でこの使用法を制限するかもしれないスタイルガイドがあることに注意してください - それは非常に小さい構文に多くの意味を詰め込みます。

27
Aaron Hall

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'
17
Sasikiran Vaddi

あなたはこれを行うことができます :-

[condition] and [expression_1] or [expression_2] ;

例: -

print(number%2 and "odd" or "even")

これは、数字が奇数の場合は "odd"、偶数の場合は "even"と表示されます。


結果: - conditionがtrueの場合はexp_1が実行され、それ以外の場合はexp_2が実行されます。

注: - 0、なし、False、emptylist、emptyStringはFalseと評価されます。 0以外のデータはTrueと評価されます。

これがどのように動作するのかです:

条件[condition]が "True"になると、expression_1は評価されますがexpression_2は評価されません。 ""および "0(ゼロ)を持つものがあれば、結果は常に固くなります。 、

0 and exp

式expはまったく評価されません。これは、0を指定した "and"は常に0に評価され、式を評価する必要がないためです。これは、コンパイラ自体がどのように動作するかをすべての言語で示したものです。

に 

1 or exp

式1は "1"で常に1になるので式expはまったく評価されません。結果が1になるので式expを評価するのは面倒ではありません。 (コンパイラ最適化手法) 

しかしの場合 

True and exp1 or exp2

2番目の式exp2は、exp1がfalseでない場合はTrue and exp1がTrueになるので評価されません。

同様に 

False and exp1 or exp2

Falseは0を書いて0で "and"を実行するのと同じなので式exp1は評価されませんが、 "or"が使われているのでexp1の後では式 "exp2"が評価されます。


注: - "or"と "and"を使用したこの種の分岐は、expression_1のTruth値がFalse(または0かNone、またはemptylist []またはemptystring '')の場合にのみ使用できます。 expression_1がFalseになると、exp_1とexp_2の間に "or"が存在するため、expression_2が評価されます。

exp_1とexp_2の真理値が何であるかにかかわらず、すべてのケースで機能するようにしたい場合は、次のようにします。 -

[condition] and ([expression_1] or 1) or [expression_2] ;

15
Natesh bhat

三項条件演算子は、単一行で条件をテストして複数行のif文を置き換えるだけで、コードをコンパクトにすることができます。

構文:

[on_true] if [expression] else [on_false] 

1-三項演算子を使用する簡単な方法:

# 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

2-タプル、辞書、ラムダを使用する直接的な方法:

# 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

3-三項演算子は、if-elseのネストとして書くことができます。

# 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
14
Ali Hallaji

答えよりもヒントがありますが(あの時間を明瞭に繰り返す必要はありませんが)、そのような構成の中でonelinerのショートカットとして使うこともあります。

if conditionX:
    print('yes')
else:
    print('nah')

、になります:

print('yes') if conditionX else print('nah')

ある人(多くの人:)はそれを非情熱的(たとえRubyのような:)としかめないかもしれませんが、私は個人的にそれをもっと自然に感じます。

12
Todor Minakov

はい、あなたはそれをそのように使うことができます: 

is_fat = True
state = "fat" if is_fat else "not fat"

三項条件演算子 についてもっと読む

10
Daniel Taub
In [1]: a = 1 if False else 0

In [2]: a
Out[2]: 0

In [3]: b = 1 if True else 0

In [4]: b
Out[4]: 1
10
ox.
a if condition else b

覚えにくい場合は、このピラミッドを覚えてください。

     condition
  if           else
a                   b 
7
shivtej

はい、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")
6
PythonLover

構文:三項演算子は次のように与えられます。

[on_true] if [expression] else [on_false]

例えば

x, y = 25, 50
big = x if x < y else y
print(big)

はい。

>>> b = (True if 5 > 4 else False)
>>> print b
True
4

Cから派生したプログラミング言語の多くは、通常、次の3項条件演算子の構文を持っています。

<condition> ? <expression1> : <expression2>

最初は、Python _ b _ enevolent _ d _ ictator _ f _ または _ l _ ife(もちろん、Guido van Rossumのことです)はそれを拒否しました(なぜならC言語に慣れていない人たちにとっては理解するのはかなり難しいからです。また、コロン記号:Pythonですでに多くの用途があります。 PEP 308 が承認された後、Pythonはついに独自のショートカット条件式を受け取りました(現在使用しているもの):

<expression1> if <condition> else <expression2>

そこで、まず条件を評価します。それがTrueを返す場合、 式1 が評価され、結果が得られます。それ以外の場合、 式2 が評価されます。 遅延評価 mechanicsのため、式は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'

お役に立てれば。

3
ARGeo

演算子は「条件付き」です。三項はちょうどそれが3つのオペランドを取ることを意味します。私達は "二項"演算子を呼ばない。条件付きでこれをやり続ける理由はありません。 if-elseよりも速いのか、それともコンパクトなのかは重要です。重要なのは、それが式であり、他の式に埋め込むことができるということです。適切に使用されると、冗長性が少なくなり、違いを見つけにくくなります。

1
David McCracken

Pythonの 条件式 に代わるものの一つは以下の通りです。

{True:"yes", False:"no"}[boolean]

次のNice拡張子があります。

{True:"yes", False:"no", None:"maybe"}[boolean_or_none]

最も短い代替手段は残ります:

("no", "yes")[boolean]

ただし、以下でyes()no()の両方の評価を避けたい場合は、代替方法はありません。

yes() if [condition] else no()
1
Walter Tross

はい:

あるboolが真であれば、変数xに何らかの値を与えたいとしましょう。 

それ以外の場合はX = 5 x = 10

X = [いくつかの値] if [これが真の場合、最初の値が評価される] else [他の値が評価される]

1
Elad Goldenberg

変数が定義されていて、それが値を持っているかどうかをチェックしたい場合は、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
0
ewwink

複数の演算子を連鎖させるためのきちんとした方法:

f = lambda x,y: 'greater' if x > y else 'less' if y > x else 'equal'

array = [(0,0),(0,1),(1,0),(1,1)]

for a in array:
  x, y = a[0], a[1]
  print(f(x,y))

# Output is:
#   equal,
#   less,
#   greater,
#   equal

0
Yaakov Bressler