Pythonでは条件式を使うことで、単一の式として条件分岐を記述できる。if文を簡潔に記述したり、式しか書けないところで条件分岐したりするために条件式を使える。
* 本稿は2021年4月2日に公開された記事をPython 3.11.5で動作確認したものです(確認日:2023年9月11日)。
# 条件式(三項演算子)の基本パターン
x = 101
s = 'odd' if x % 2 else 'even'
print(s) # odd
# 条件式のネスト
s = 'positive' if x > 0 else 'negative' if x < 0 else 'zero'
print(s) # positive
# 内包表記と条件式
l1 = [3, 4, 6, 0, 1]
l2 = ['odd' if x % 2 else 'even' for x in l1]
print(l2) # ['odd', 'even', 'even', 'even', 'odd']
# ラムダ式と条件式
l1 = [3, 4, 6, 0, 1]
it = map(lambda x: 'odd' if x % 2 else 'even', l1)
l2 = list(it)
print(l2) # ['odd', 'even', 'even', 'even', 'odd']
条件式は、「ある条件が成り立ったときにはこの値、そうでなかったらこの値」という意味の式である。「条件」「その条件が成立したときの値」「成立しなかったときの値」という3つの項で構成されるので三項演算子とも呼ばれる。条件式を使うと、シンプルな条件分岐処理を1行で簡潔に記述できる。
条件が成立したときの値 if 条件 else 条件が成立しなかったときの値
if文は文が書ける部分にしか書けないが、条件式は式が書けるところに記述できるので、内包表記やラムダ式などで条件に応じて値を変更したいといったときに便利に使える。
以下に例を示す。
x = 101
s = 'odd' if x % 2 else 'even'
print(s) # odd
この例ではxを2で割ったときに、その余りが1(真)なら'odd'が、余りが0(偽)=割り切れたなら'even'が変数sに代入される。このときに注意すべきは「条件が成立したときの値」と「条件が成立しなかったときの値」に書けるのは、何らかの値を持つ式(リテラル値、関数呼び出しなど)だけである点だ(print関数のようにNoneを返す=戻り値を持たないものでもよいが、Pythonの「文」は記述できない)。if文は複合文であり、そのブロックには文を記述できるが、条件式では文を記述できない点には注意しよう。
例えば、以下のコードにあるif文を条件式を用いて1行に書き直そうとしたら、「raise ValueError('not a number')」は文(raise文)で条件式中には記述できないので、exec関数を使ってraise文を実行するような方法を取る必要がある(if文を書ける場所で、そこまでして条件式を使う必要はないだろう)。
s = input('input a number: ')
if s.isdecimal():
x = int(s)
else:
raise ValueError('not a number')
# NG:x = int(s) if s.isdecimal() else raise ValueError('not a number')
# OK:x = int(s) if s.isdecimal() else exec('raise ValueError("not a number")')
条件式はネストさせることも可能だ。以下に例を示す。
x = 101
s = 'positive' if x > 0 else 'negative' if x < 0 else 'zero'
print(s) # positive
条件式の最初の条件が「x > 0」となっているので、変数xの値が正値であれば、この条件式の値は'positive'となる。条件が成立しなかったときの値は、さらに条件式を使って「'negative' if x < 0 else 'zero'」と記述している。ネストした条件式の条件は「x < 0」なので変数xの値が負値であれば、条件式の値は'negative'となり、「x > 0」「x < 0」という2つの条件をどちらも満たさなかったときの値は'zero'となる。
このように条件式をネストさせることは可能だが、過剰にネストさせるとコードの可読性が落ちるので、そのような状況であれば素直にif文を記述するのがよいだろう。
内包表記を使って、何らかの反復可能オブジェクト(リストなど)を基に新たな反復可能オブジェクトを生成する場合、元の要素の値が特定の条件を満たすときと満たさないときとで、新しい要素の値を違うものにしたいというときにも条件式が役に立つ。
以下に例を示す。
l1 = [3, 4, 6, 0, 1]
l2 = ['odd' if x % 2 else 'even' for x in l1]
print(l2) # ['odd', 'even', 'even', 'even', 'odd']
この例では、元の要素が奇数なら新しい要素を'odd'とし、偶数であれば'even'とする新しいリストを内包表記を使って生成している。なお、これはPythonに組み込みのmap関数を使って次のようにも書ける。
l1 = [3, 4, 6, 0, 1]
it = map(lambda x: 'odd' if x % 2 else 'even', l1)
l2 = list(it)
print(l2) # ['odd', 'even', 'even', 'even', 'odd']
この例ではmap関数に渡す関数としてラムダ式を記述している。ラムダ式に関数ボディーとして記述できるのは単一の式なので、条件分岐を含んだ処理を単一の式として記述できる条件式は便利に使えるはずだ。
Copyright© Digital Advantage Corp. All Rights Reserved.