2012-04-15 9 views
0

私はPythonのバージョン< 2.5を負担する必要があり(それは仕様については2.4.3です)最良の方法は<2.5

三項演算子は2.5から始まるPythonで紹介したようです。慣れていない人のために、このような、Pythonで三項演算子は> = 2.5外観:

def do_ternary(flag): 
    return "foo" if flag else "bar" 

私は、Pythonの初期のバージョンでこれをエミュレートするために、いくつかの解決策を知っているように思います。私は確かにそれを行うことができます...他には、私はいくつかの生産レベルのコードを置くために恥ずかしいではないよりpyononicを探しています:)

ありがとう!これはpythonでとても似andor作品として働く

test and true_value or false_value 

+0

フラグがある場合はあなたの反対です:戻り値 "foo" else:戻り値 "bar"は十分にスタイリッシュではありませんか?それとも具体的な理由がありますか? – mfrankli

+0

論理はうまくいますが、三項演算子ではありません。それは実際には「スタイリッシュ」なのかどうかという問題ではなく、コード分解とクリーンなコードの作成です。私は本当に私のコード内にif ... elseステートメントのツリー全体を持っているのが好きではありません。 –

+2

テストが真であれば何かをしたいときは、 '' if ...:... else:... ''はかなり妥当と思われます。 _terse_と_readable_を混同しないでください。両方を行うことができない場合は、読み込み可能なものは常に勝つべきです。 –

答えて

4

で、プレーン・オールif:ステートメントを使用して、本当にエレガントな神託のソリューションのように思えるが見つかりました:

def _if(test): 
    return lambda alternative: \ 
       lambda result: \ 
        [delay(result), delay(alternative)][not not test]() 

def delay(f): 
    if callable(f): return f 
    else: return lambda: f 

>>> fact = lambda n: _if (n <= 1) (1) (lambda: n * fact(n-1)) 
>>> fact(100) 
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000L 

これについてどう思いますか?それは私の意見ではかなりきれいに見えます。

+0

私はそれがかなりクールだと思う:)私は、しかし、可読性が行く限り、言わなければならない... if ... thenステートメントはかなり読みやすいです。 –

+1

ええ、他にも読みやすいものがあれば同意しますが、私は創造的であり、そのトリックを行うための1つのライナーを持っています:)これまでのところ、私はこれと@ TokenMacGuyのことは信じています。ほとんどを考慮してm。 –

+0

これはおそらく私がこれを行うのを見ている最も読み難いコードだと思います。それはコードのクールなビットですが、私は実際にそれが実際に読者や作家に任意の利益を提供すると感じていません。 –

1

これを行うために使用される古典的な 'トリック' である

x or y -> if x is false, then y, else x 
x and y -> if x is false, then x, else y 

Source

これは、我々意味しますおおよそ同じ結果を得ます - true_valueTrueと評価される限り、 lowingが希望ない作品:[]として

flag and [] or "bar" 

Falseに評価されます。

私はこれに慣れていない限り、単にif/elseブロックを使用するよりも読みにくいと主張しています。

だから私は使用してお勧めする:

if test: 
    return true_value 
else: 
    return false_value 

(譲渡または任意の必要な場所に置き換えリターン)。

+5

'true_value'が' False'と評価されるものなら、これは期待どおりに動作しません。 'フラグと[]または' bar 'で '' – Dougal

+0

@Dougal +1。私はそのメモを追加します - 私はこれを自分では好きではなかったので、それを使ったことはありませんでした。その問題を忘れました。 –

4

整数が必要な場合/Trueになると、0/になるので、一般的なトリックはリストインデックスを使用することです。ケースでテストがy虚偽または真実-yのではなく、ブール値であってもよいし、最初のテストを確保するためにその良い練習はbooleanです:

["bar", "foo"][bool(flag)] 

は、あなたの質問では三元と同じ出力を生成します。

編集:真と偽の値の両方が評価されるため、これは副作用を伴う可能性があるため、Dougalは3者とは多少異なる動作をする可能性があることを指摘しています。

+0

これは良い選択肢ですが、読みやすさという点では少し不足していると感じています。三項演算の利点の1つは、読みやすいことです。これがうまくいく間に、コードを複雑にすることもわかります。 –

+0

これも短絡評価ではありません。 – Dougal

+0

@Dougalそれは良い点です。 –

7

if/elseがないこと、物事のすべてを行い正しい方法は、次のとおりです。

(condition and (yes_value,) or (no_value,))[0] 

短絡の両方を行い、yes_valueがfalseyそのものであるときの問題を解決しています。明らかに、もしあなたがこのクルージングを避ける理由があれば、それをしてください。あなたの例では、両方の条件が定数式ですので、あなたが行うことができます。

{True: yes_value, False: no_value}[bool(condition)] 

以上簡潔:

(no_value, yes_value)[condition] 

あなたがを行う場合、短いcircutが必要ですが、あなたはその確信していますyes_valueあなたはタプル出てトリミングすることができ、falseyことはありません:

condition and yes_value or no_value 

をしかしyes_valueが実際に一定である場合、それはおそらく唯一の有効なのです。これらのどれもが、あなたの好みやニーズに合わせていない場合は、ちょうど私がウェブ上で見ていた中間変数実際

if condition: 
    result = yes_value 
else: 
    result = no_value 
関連する問題