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


6046

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


149
上記のコメントで参照されているPython 3.0の公式ドキュメントでは、これは「conditional_expressions」と呼ばれ、非常に不可解に定義されています。そのドキュメントには「3項」という用語も含まれていないため、何を探すべきかを正確に知らない限り、Googleでそれを見つけるのは困難です。バージョン2のドキュメントはやや役に立つとへのリンクを含んでいる「PEP 308」この質問に関連した興味深い歴史的な文脈の多くが含まれ、。
nobar 2013年

26
「3値」(3つの入力がある)は、この強制の結果的なプロパティであり、コンセプトの定義プロパティではありません。例:SQLはcase [...] { when ... then ...} [ else ... ] end同様の効果がありますが、3値ではありません。
user313114

10
また、ISO / IEC 9899(Cプログラミング言語標準)のセクション6.5.15では、「条件付き演算子」と呼ばれています
user313114

9
ウィキペディアはこれを記事「?:」で徹底的にカバーしています。
HelloGoodbye 2016年

9
nobarのコメント以来、条件式のドキュメントは、条件式(「三項演算子」と呼ばれることもあります)と記載するように
Scott Martin

回答:


7044

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

a if condition else b

最初conditionに評価され、次にaまたはbブール値のいずれかに基づいて評価または返されますcondition。場合はcondition評価するにTrueは、a評価され、返されるがb無視されるか、あるいは時にb評価され、返されるがa、無視されます。

これconditionは、true aが評価されるだけで評価されないので短絡を許可しますbが、conditionfalse 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ます。

公式ドキュメント:


269
順序はコーダーにとって奇妙に見えるかもしれませんがf(x) = |x| = x if x > 0 else -x、数学者にとっては非常に自然に聞こえます。ほとんどの場合、Aと同じように理解できますが、Cの場合はBを実行する必要があります...
yota

121
ご使用の際は、操作順序にご注意ください。たとえば、行z = 3 + x if x < y else y。との場合x=2y=14が得られると期待できますが、実際にz = 3 + (x if x > y else y)は1 が得られます。これが正しい使用方法です。
Kal Zekdor 2016年

11
ポイントは、結果に値を追加するなど、条件が評価された後に追加の評価を実行する場合、両側に追加の式を追加する(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
Kal Zekdor

4
@MrGeek、私はあなたが意味を理解しているので、基本的に操作をネストしているでしょう: `" foo "if Bool else(" bar "if Bool else" foobar ")`
Dimesio

3
数学では基礎となる概念に常に頼るので、プログラマーは数学者よりも正確な正しい定式化を必要とします。説得力のある引数は%演算子であり、数学で「mod」が使用される方法を模倣することは災難でした。だから、私はあなたの主張を受け入れません。それは帝国の単位に固執するようなものです。Groetjes Albert
アルバートファンデルホルスト

798

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

(falseValue, trueValue)[test]

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

(falseValue, trueValue)[test == True]

または、組み込みを使用しbool()ブール値を保証できます。

(falseValue, trueValue)[bool(<expression>)]

590
これは常にすべてを評価するのに対し、if / else構文は勝った式のみを評価することに注意してください。
SilverbackNet

117
(lambda: print("a"), lambda: print("b"))[test==true]()
ダスティンゲッツ

15
[]s 内には任意の式を使用できることに注意してください。また、安全のために、と書いて真実性を明示的にテストできます[bool(<expression>)]。このbool()関数はv2.2.1以降で使用されています。
martineau

12
でインデックス化することにより、辞書に-だけ一度か二度、それを行って-私は、同様のトリックをやったTrueFalse:キーとして {True:trueValue, False:falseValue}[test] 私は、これは任意のあまり効率的であるかどうかわからないが、それは全体の少なくとも回避でありません「エレガント」対「醜い」議論。intではなくbooleanを扱っていることは明白です。
JDM 2016年


338

2.5より前のバージョンの場合、トリックがあります。

[expression] and [on_true] or [on_false]

on_true ブール値がfalseの場合、誤った結果をもたらす可能性があります。1
それは式を左から右に評価する利点がありますが、私の意見ではより明確です。

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


67
解決策は(testおよび[true_value]または[false_value])[0]を使用することで、このトラップを回避します。
ThomasH 2009年

5
3項演算子は通常、より高速に実行されます(場合によっては10〜25%)。
火山

7
@volcanoソースはありますか?
OrangeTux 2014

4
@OrangeTuxこれが逆アセンブルされたコードです。ThomasHが提案した方法を使用するとさらに遅くなります。
mbomb007

265

<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

83
これは、3項演算子の主な目的である値の選択を強調しています。また、複数の3項を1つの式にチェーンできることも示しています。
Roy Tinker

6
@Craig、私は同意しますが、括弧がない場合に何が起こるかを知ることも役に立ちます。実際のコードでは、私も明示的な括弧を挿入する傾向があります。
Jon Coombs 2014

159

ドキュメントから:

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

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

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

バージョン2.5以降で新規。


120

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")

出典:?:WikipediaのPython


1
result = {1: x, 0: y}[a > b]別の可能な変形である(TrueそしてFalse実際の値を持つ整数である10
ウォルターTross

98

残念ながら、

(falseValue, trueValue)[test]

ソリューションには短絡動作がありません。したがって、両方falseValuetrueValue関係なく、条件の評価を行っています。これは最適とは言えない、またはバグが多い(つまり、両方trueValuefalseValue方法であると副作用を持つことができます)。

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

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

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

そして、話は続きます-言及された3つの解決策から選択することは、短絡機能を備えること、少なくともЗython2.5を使用すること(IMHOはもはや問題ではない)、および「trueValue-evaluates-to-false」エラーを起こしにくいことの間のトレードオフです。 。


2
lambdasトリックのタプルは機能しますが、三項演算子の約3倍の時間がかかります。それがの長いチェーンを置き換えることができる場合にのみ、それは合理的な考えである可能性が高いですif else if
パーキンス

72

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

ここで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


5
それは独断的に聞こえるかもしれません。しかし本質的に言っているのは、Python構文は三項演算子を見たことのない人に理解される可能性が高いということです。一方、その意味を最初に言わない限り、通常の構文を理解する人はほとんどいません。
fralau

1
Algol68:a = .if。.true。。その後。1 .else。0 .fi。これは次のように表すこともできます。
アルバートファンデルホルスト

63

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

[on_true] if [cond] else [on_false]

古いPythonでは、3項演算子は実装されていませんが、シミュレーションすることは可能です。

cond and on_true or on_false

けれどもが、あれば潜在的な問題があり、condと評価するTrueon_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バージョンと互換性があります。


2
動作は同じではありません- q("blob", on_true, on_false)戻りますon_falseが、on_true if cond else on_false戻りますon_true。この問題を回避するには、交換することであるcondcond is not Noneそれが完璧なソリューションではないが、これらのケースで。

5
bool(cond)代わりにしないのはなぜcond is Trueですか?前者はの真偽をcondチェックし、後者はTrueオブジェクトとのポインタの等価性をチェックします。@AndrewCecilによって強調されているように、"blob"真実ですがそれはis not True
JonasKölker2013

うわー、それは本当にハックに見えます!:)技術的には[on_false, on_True][cond is True]、式を短くすることもできます。
アーセニー2014

この答えには短絡はありません。on_trueとon_falseを呼び出すのにコストがかかる場合、これは悪い答えです。
ハッカー

44

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

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

38

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

これはセマンティクスで同等です。一部のスタイルガイドでは、わかりやすくするためにこの使用法を制限している場合があることに注意してください。非常に小さな構文に多くの意味が詰め込まれています。


1
expression1 or expression2expression1 || expression2javascript と同様に、同じ欠点と利点がある
JSDBroughton

1
ありがとう、@ selurvedu-正直になるまで混乱する可能性があります。私は難しい方法を学んだので、あなたの方法はそれほど難しくないかもしれません。;)elseなしでifを使用すると、ジェネレータ式またはリスト内包の最後に反復可能オブジェクトがフィルタリングされます。前面では、これは3項の条件付き演算であり、elseが必要です。乾杯!!
アーロンホール

@AaronHall expressionNすべてのインスタンスでメタ構文を使用することには一貫性がありますが、条件付きテスト式と2つの結果式を区別するネーミングを使用すると理解しやすいかもしれません。例えば、result1 if condition else result2。これは、ネスト(別名チェーン)の場合に特に顕著ですresult1 if condition1 else result2 if condition2 else result3。この方法でどれほど読みやすくなるか見てください。
tchrist

@tchristレビューをありがとう-変更履歴を見ると、この投稿には現在2つの改訂があります。私の他の答えのほとんど、特に上位のものは何度も何度も再訪されました。コミュニティーWikiのステータスからはコンテンツのクレジットが得られないため、この回答には決して注意が向けられず、投票はありません。現在、これを編集する時間がないので、カエルはいつそれが私の注目を引くかを知っています。トップアンサーを編集したことがわかります。この投稿から私の資料を自由に借りたり引用したりしてください(適切な場合は引用してください)
アーロンホール

23

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するのですか?
Grijesh Chauhan

5
@GrijeshChauhanたとえば「関数呼び出し」などの「複雑な」式では、これはどちらの場合でも実行されます。これは望ましくないかもしれません。
glglgl 2014

20

三項条件演算子を使用すると、複数行のif-elseを置き換えて単一行で条件をテストできるため、コードがコンパクトになります。

構文:

[on_true] if [式] 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

1
三項演算子はネストされたifよりも(メモリ内で)小さく、高速であることに注意してください。また、ネストされたものif-elseは実際には三項演算子の書き換えではなく、aとbの選択値に対して異なる出力を生成します(特に、1つが奇妙な__ne__メソッドを実装するタイプの場合)。
Perkins

19

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

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

例:-

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

これは、数値が奇数の場合は「奇数」、偶数の場合は「偶数」を出力します。


結果:- 条件がtrueの場合はexp_1が実行され、そうでない場合はexp_2が実行されます。

注意 :- -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_1falseと評価、xとなります1、ではありませんexpression_1。受け入れられた答えを使用してください。
moi

18

答えというよりはヒントです(100分の時間の間、明白なことを繰り返す必要はありません)が、そのような構成体でワンライナーショートカットとして使用することがあります。

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

は、次のようになります。

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

一部の(多くの:)はunpythonic(さえ、ルビーっぽい:)として不快に思うかもしれませんが、個人的にはより自然に感じます。つまり、通常の表現方法に加えて、コードの大きなブロックで少し視覚的に魅力的です。


5
print( 'yes' if conditionX else 'nah' )はあなたの答えよりも好きです。:-)
frederick99 2017

それはprint()両方の場合にしたい場合-そしてそれがもう少しpythonicに見える場合、私は認めざるを得ません:)しかし、式/関数が同じでない場合-のようにprint('yes') if conditionX else True- print()唯一の真実を取得するにはconditionX
Todor

Frederick99の発言print('yes') if conditionX else print('nah')を補足すると、Python2でSyntaxErrorが発生することを回避する別の理由があります。
Thierry Lathuille、

構文エラーが発生する唯一の理由は、Python 2ではprintがステートメントprint "yes"であるのに対し、Python 3ではprintが関数であるためprint("yes")です。これは、ステートメントとして使用するか、より良い方法で解決できますfrom future import print_function
Todor Minakov、2018年

18
a if condition else b

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

     condition
  if           else
a                   b 

14

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()評価されます。


10

から派生した多くのプログラミング言語には、C通常、3項条件演算子の次の構文があります。

<condition> ? <expression1> : <expression2>

まず、Python Bの enevolentのDの ictator FまたはLのそれが使用されていない人々のために理解することは非常に難しいので、IFEは、(私はもちろんのグイド・ヴァンロッサムを意味する)、(非Python的スタイルとして)それを拒否しCた言語。また、コロン記号は:すでにで多くの用途がありPythonます。PEP 308が承認された後、Pythonついに独自のショートカット条件式(現在使用しているもの)を受け取りました。

<expression1> if <condition> else <expression2>

したがって、最初に条件を評価します。が返された場合Trueexpression1が評価されて結果が返されます。それ以外の場合は、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'

お役に立てれば。


10

すでに答えたように、はい、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:もちろん、短絡評価は三項演算子ではありませんが、多くの場合、短絡で十分な場合に三項が使用されます。


1
そのshort-circuit評価に賛成票を投じます。
CodeIt、

7

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

さらに詳しく説明するためにどれが大きいかを確認する1行のステートメントの例を追加しました
PythonLover

1
print Python2でSyntaxErrorが発生するため、これは本当に良い選択ではありません。
Thierry Lathuille、2018年

@Thierry Lathuilleここでは、printステートメントではなくprint()関数を使用しました。print関数はPython 3用で、printステートメントはPython 2用です
PythonLover

質問はすでにSOで行われています。Python2で試してみてください。自分で確認できます。'print(' hello ')はPython 2.7では完全に有効な構文ですが、構文解析の方法により、上記のコードはSyntaxErrorをスローします。
Thierry Lathuille、

2

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]
>>> 

上記li1Noneそのままで機能し、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は構文が豊富な言語であり、イブラーにはすぐにはわからない多くの慣用的なトリックがあります。しかし、基礎となるシステムの仕組みを学び、理解すればするほど、それを高く評価するようになります。


1

その他の答えは、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)

-2

変数が定義されていて、値があるかどうかを確認したい場合は、 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

1
同様の問題には役立ちますが、これは三項条件式ではありません。それは置き換えるために機能しますx if x else yが、そうではありませんx if z else y
パーキンス

-2

複数の演算子をチェーンするためのきちんとした方法:

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

-2

デフォルトのpython構文val = a if cond else bは扱いにくいので、時々これを行います:

iif = lambda (cond, a, b): a if cond else b
# so I can then use it like:
val = iif(cond, a, b)

もちろん、それは常に両側(aとb)を評価するという欠点がありますが、構文は私にはずっと明確です


これは、単純なval = a if cond else bステートメントよりも作業量が2倍多く、RAM使用量が多く、難読化されているようです。
eatsfood

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.