Python bite: 条件式(conditional expression)
Tagged:

Python には C/C++ や Java で言うところの「条件式 (conditional expression)」が文法上存在しません。

但し、and/or による式連結を行うことで、 同等の効果を得ることができます。 例えば C/C++ における (condition ? A : B) に相当する効果を得るには:

var = (condition and A or B)
条件式の代替表記

しかし、 このような Python 表記は、 あくまで and/or による式連結であって、 条件式ではありません。

Python の代替表記では、 condition が成立していても、 A が偽値の場合には、 式の値としては B が評価されます。 たとえば:

A = 0
B = 100
var = (condition and A or B)
var は常に 100

上記の例では A が False 扱いされる値である 0 なので、 condition and A は常に False となり、 var = (False or B) と等価になります。

つまり、 A が真偽判定において真値とならない場合 (例えば 0 や空文字列)には、 条件式の代替手段として (condition and A or B) という記述を用いると咬まれます

上記のような単純な例ならまだしも、 引数として指定されるために A の値に関与できないような局面で、 安全な実行を保証するためには、 if/else を用いて蛇の巣を迂回するべきですが、 1行で済む初期化に4行(頑張って詰めても2行) も必要かと思うと気分が萎えませんか?

捕捉

西尾泰和氏の「Pythonでワンライナーを作成する際のノウハウ集」に、 「空でない配列・タプルは True 扱いされる」 ことを利用してこの問題を回避する手法が紹介されていました。

A = 0
B = 100
var = (condition and [A] or [B])[0]
var 値は条件に依存

なるほど、これなら上手く機能しますね。

ちなみに、 この場合の配列は使い捨てのオブジェクトになりますから、 なるだけコスト安の方が良いのですが、 Python ではタプルと配列はどちらのコストが安いのでしょうね? 実装屋の感覚としては、 余計な管理構造がいらないタプルの方だと思うのですが…。