21

私が読んだことから、組み込みの三項演算子が存在しないことがわかりました(それについてもっと知りたいと思います)。

代わりに次のコードを見つけました。

def val():
    var = float(raw_input("Age:"))
    status = ("Working","Retired")[var>65]
    print "You should be:",status

このコードがどのように機能するのか理解できませんでした。コードが実際にどのように機能しているかを誰かに説明してもらえますか?また、三項演算子が存在しない理由を知りたいと思います。これに関する参照やリンクは、非常に役立ちます。

WindowsVistaでPython2.6.4を実行しています。

4

12 に答える 12

51

Pythonには、Cなどの三項演算子のような構造があります。これは次のように機能します。

my_var = "Retired" if age > 65 else "Working"

そして、このCコードと同等です:

my_var = age > 65 ? "Retired" : "Working";

投稿したコードがどのように機能するかについては、次の手順を実行してみましょう。

("Working","Retired")

要素「Working」をインデックス0に、「Retired」をインデックス1に持つ2タプル(不変リスト)を作成します。

var>65

varが65より大きい場合はTrueを返し、そうでない場合はFalseを返します。インデックスに適用すると、1(True)または0(False)に変換されます。したがって、このブール値は、同じ行に作成されたタプルへのインデックスを提供します。

Pythonに常に三項演算子がないのはなぜですか?簡単な答えは、Pythonの作者であるGuido van Rossumがそれを好きではなかった、または望まなかったということです。これは、コードを混乱させる可能性のある不要な構造であると考えているようです。 Cはおそらく同意することができます)。しかし、Python 2.5の場合、彼は上で見た文法を容赦して追加しました。

于 2009-12-22T15:31:54.327 に答える
9

Python(2.5以降)には、実際に探しているものの構文があります。

x = foo if condition else bar

conditionがTrueの場合はxに設定されfoo、そうでない場合はに設定されbarます。

例:

>>> age = 68
>>> x = 'Retired' if age > 65 else 'Working'
>>> x
'Retired'
>>> age = 35
>>> y = 'Retired' if age > 65 else 'Working'
>>> y
'Working'
于 2009-12-22T15:24:40.727 に答える
8

Trueは1にキャストし、Falseは0にキャストするため、var=70の場合

("Working","Retired")[var>65]

になります

("Working", "Retired")[1]

ちょっといいショートカット...でも、単純な条件以外では少し混乱する可能性があるので、TMの提案を使用します

"Retired" if var > 65 else "Working"
于 2009-12-22T15:31:01.163 に答える
7

リストへのインデックス作成

の用法

[expression_when_false, expression_when_true][condition] # or
(expression_when_false, expression_when_true)[condition]

PythonではTrueが1に等しい(しかしそうではない!)1であり、Falseが0に等しい(しかしそうではない!)という事実を利用します。上記の式は2つの要素のリストを作成し、条件の結果を使用してインデックスを作成します。 1つの式のみをリストして返します。この方法の欠点は、両方の式が評価されることです。

および-またはショートカット

Pythonの作成以来、この操作の形式がありました。

condition and expression_when_true or expression_when_false

これはショートカットを取り、1つの式のみを評価しますが、バグが発生しやすい欠点があります。expression_when_trueはtrue以外の値に評価されてはならず、そうでない場合、結果はexpression_when_falseになり ます。およびはPythonで「短絡」しており、次のルールが適用されます。andor

a and b #→ a if a is false, else b
a or b  #→ a if a is true, else b

条件がfalseの場合、 expression_when_trueは評価されず、結果はexpression_when_falseになります。OTOH、条件がtrueの場合、結果は(expression_when_trueまたはexpression_when_false);の結果になります。上記の表を参照してください。

三項条件演算子

もちろん、Python 2.5以降、三項条件演算子があります。

expression_when_true if condition else expression_when_false

奇妙な(Cのような三項条件演算子に慣れている場合)オペランドの順序は、多くのことに起因しています。一般的な意図は、条件がほとんどの場合真である必要があることです。これにより、最も一般的な出力が最初に来て、最も目立つようになります。

于 2009-12-22T20:32:04.290 に答える
2

短絡ブール式

論理演算を短絡するオプションもあります。

>>> (2+2 == 4) and "Yes" or "No"
'Yes'
>>> (2+2 == 5) and "Yes" or "No"
'No'

あなたの例では:

>>> (int(raw_input("Age: ")) > 65) and "Retired" or "Working"
Age: 20
'Working'
>>> (int(raw_input("Age: ")) > 65) and "Retired" or "Working"
Age: 70
'Retired'

この手法の詳細については、「魅力的なPython:Pythonでの関数型プログラミング」パート1を参照してください。

于 2009-12-28T11:17:44.997 に答える
0

Python 2.6以降の場合:

print "You should be {0}.".format("retired" if var>65 else "working")

Python 3.1以降の場合:

print ("You should be {}.".format("retired" if var>65 else "working"))
于 2009-12-22T15:29:43.120 に答える
0

あなたが投稿したコードでは、次の行は三元をエミュレートしています:

status = ("Working","Retired")[var>65]

ここで、タプルは()または( )のいずれかに評価される("Working","Retired")インデックスでアクセスされます。インデックスでアクセスすると、;になります。インデックスの場合は「リタイア」になります。これは、条件付き割り当てを行うためのかなりあいまいな方法です。前述のように、py2.5で導入された通常の3項構文を使用します。[var>65]True1False00status'Working'1

于 2009-12-22T15:31:28.017 に答える
0

これは、Pythonの三項演算子を使用したフォームです

def val():
    var = float(raw_input("Age:"))
    status = "Retired" if var > 65 else "Working"
    print "You should be:",status

示したコードは少し注意が必要です。要素が0と1の位置にある2つの要素のタプルを作成します。正しい要素を選択するには、ブール値を返す条件を使用しますが、Pythonのブール値は整数であるため、特別なものとして使用できます。インデックス(0または1のいずれかになります)。

于 2009-12-22T15:32:16.860 に答える
0

「明示的は暗黙的よりも優れている」ため、元々三項演算子はありませんでしたが、それは非pythonicと見なされていました。私もPythonの三項演算子があまり好きではありませんが、それは存在します:

x = foo if condition else bar

TMによって示されるように。

については、ブール値status = ("Working","Retired")[var>65]var > 65返します。TrueまたはFalseのいずれか。ただし、Pythonはブール型を非常に弱く扱います。一部のコンテキストではTrueis1Falseisです。0を実行してチェックアウトできます>>> True == 1

于 2009-12-22T15:32:52.020 に答える
0
status = ("Working","Retired")[var>65]

この行は、65より大きいvar>65かどうかに応じて、式が1または0を返すため、三項演算子として機能します。varしたがって、の場合var>65、行は次のようになります。

status = ("Working","Retired")[1]

つまり、シーケンスの2番目の要素です("Working","Retired")。奇妙に見えますが、代わりに次のように書くとそうではありません。

status_sequence = ("Working","Retired")
status = status_sequence[1]

そうstatus = "Retired"

同様に、もしそうvar<=65なら

status = ("Working","Retired")[0]

およびstatus = "Working"

于 2009-12-22T15:34:53.030 に答える
0

そのコードの「status=」行だけが、三項演算子のようなものを実装しています。

status = ("Working","Retired")[var>65]

これにより、インデックス0に文字列'Working'、インデックス1に'Retired'の2要素タプルが作成されます。その後、式の結果を使用して、そのタプルにインデックスを付け、2つのアイテムのいずれかを選択しますvar > 65

この式は、varの値が65より大きい場合、True(1に相当するため、「Retired」を選択)を返します。それ以外の場合は、False(0に相当するため、「Working」を選択)を返します。

ただし、特定の例では重要ではありませんが、このアプローチと三項演算子には重要な違いがあります。タプルインデックスアプローチでは、両方の値が評価されますが、返されるのは1つだけです。三項演算子を使用すると、2つの値のうち1つだけが実際に評価されます。これは「短絡」動作と呼ばれます。次のような場合に問題になる可能性があります。

status = funcA() if var > 65 else funcB()
status = (funcB(), funcA())[var > 65]

最初のケースでは、 funcA()またはfuncB()のいずれかが呼び出されますが、両方が呼び出されることはありません。後者の場合、両方が最初に呼び出され、結果がタプルに格納されます。次に、1つだけが選択され、タプルは破棄されます。

これは、funcA()またはfuncB()のいずれかに「副作用」があるかどうかを理解するために特に重要です。つまり、実行時に他のデータが変更されます。

于 2009-12-22T15:35:37.333 に答える
0

ここで与えられた答えに基づいて完全な答えを与えようとしています。

あなたが見つけた方法(あまり読みにくいので、これは使用しないでください):

def val():
    var = float(raw_input("Age:"))
    status = ("Working","Retired")[var>65]
    print "You should be:",status

Python 2.5以降の構文を使用する:

def val():
    var = float(raw_input("Age:"))
    status = "Working" if var>65 else "Retired"
    print "You should be:",status

一部の人々がまだ好んでいる他の一般的な方法を使用する:

def val():
    var = float(raw_input("Age:"))
    status = var>65 and "Working" or "Retired"
    print "You should be:",status

オペランドの順序はCの三項演算子と同じであるため、私は個人的に最後を使用する傾向があります。

編集: 最後のアプローチ(thx Roberto Bonvallet)でいくつかの問題が見つかりました。
ウィキペディアから:

式が(偽の)op1ではなくop2(真偽であるかどうかにかかわらず)を返すため、op1が「偽の」値(None、False、0、空のシーケンスまたはコレクションなど)である可能性がある場合、このコードは壊れます。

したがって、私の最後の提案は、2.5以上の三項演算子を使用することです。これは、シンプルで読みやすく、短絡動作を提供するためです。

于 2009-12-22T15:39:14.147 に答える