条件分岐はその名の通り、ある条件に従って処理を分岐させるものである。
フローチャートで見ると分かりやすいかもしれない。
![flowchart of if flowchart of if](https://interaktiv.chemie.uni-mainz.de/programming/images/if-basic-none.png)
これは次のような意味である。 まず (1) が実行される。 次の菱形が、指定された条件が成立しているかどうかを調べる部分である。 その結果、「はい」であれば下へいき、そのまま (2) と (3) を実行する。
![flowchart of if flowchart of if](https://interaktiv.chemie.uni-mainz.de/programming/images/if-basic-true.png)
もし「いいえ」であれば、(2) を飛ばして(3)へ行く。
![flowchart of if flowchart of if](https://interaktiv.chemie.uni-mainz.de/programming/images/if-basic-false.png)
従って、
-
「はい」の場合:
-
(1) → (2) → (3)
-
-
「いいえ」の場合:
-
(1) → (3)
-
と実行されることになる。
図のように条件が成立するかしないかで二手に分かれているので、これを「条件分岐」という。
では具体的な例で見てみよう。
基本形 (1)
ある条件が成立した場合にのみ処理させるには、
if 条件:
# 条件成立時の処理
と書く。
例えば、「変数 $x$ の値が正だったら、 positive
と表示する」プログラムは次のようになる。
if x > 0:
print("positive")
関数定義の時と同様に、条件 (ここでは x > 0
) が成立したときの処理をインデントして書く。
この例では条件成立時に実行される部分は一行のみだが、複数行でも構わない。
フローチャートで見てみよう。
![flowchart of if flowchart of if](https://interaktiv.chemie.uni-mainz.de/programming/images/if-none.png)
$x$ の値が値が正だったら、次のような処理の流れになる。
![flowchart of if flowchart of if](https://interaktiv.chemie.uni-mainz.de/programming/images/if-true.png)
$x$ の値が値が正ではなかったら、次のような処理の流れになる。
![flowchart of if flowchart of if](https://interaktiv.chemie.uni-mainz.de/programming/images/if-false.png)
以下のプログラムを入力し、実行してみよ。
また一行目の x
の値をいろいろ変えて試してみよ。
x = 1
if x > 0:
print("positive")
基本形 (2)
ある条件が成立した場合は A を、しなかった場合は B を実行するようなプログラムは、
if 条件:
# A: 条件成立時の処理
else:
# B: 条件非成立時の処理
と書く。 例えば、「変数 $x$ の値が負だったら negative を表示し、そうでなかったら zero or positive を表示する」プログラムは、
if x < 0:
print("negative")
else:
print("zero or positive")
となる。
以下のプログラムを入力し、実行してみよ。
また一行目の x
の値をいろいろ変えて試してみよ。
x = 0
if x < 0:
print("negative")
else:
print("zero or positive")
この場合のフローチャートを描いてみよ。 基本形 (1) との違いは何だろうか?
基本形 (3)
基本形 (2) では正の場合と 0 の場合が一緒に表示されていた。 当然 $x$ が正か 0 か 負か、で処理を分けたいであろう。
これは、プログラミング的には(条件分岐的には)「変数 x
の値が負だったら negative を表示し、そうでなかった場合、もし変数 x の値が 0 なら Zero
を表示し、そうでなければ positive を表示する」となる。
これを素直に書くと、次のようになる。
(なお、「 a
と b
が等しい場合」は a == b
と書く (後述))
# ! 望ましくない書き方 !
if x < 0:
print("negative")
else:
if x == 0:
print("zero")
else:
print("positive")
これは間違いではないが、見通しが良くないので、避けるべき書きかたである。 この場合は、
if x < 0:
print("negative")
elif x == 0:
print("zero")
else:
print("positive")
と書くのが良い。
elif
(else if の意) というのが重要な部分である。
-
以下のプログラムを入力し、実行してみよ。 また一行目の
x
の値をいろいろ変えて試してみよ。 -
このプログラムのフローチャートを描け。
x = 0
if x < 0:
print("negative")
elif x == 0: # == (等号二つ) であることに注意
print("zero")
else:
print("positive")
この elif
は複数書くこともできる。
例えば:
x = 0
if x < -1:
print("< -1")
elif x < 0:
print("negative but not < -1")
elif x == 0:
print("zero")
else:
print("positive")
print("End")
-
このプログラムを入力し、実行してみよ。 また一行目の
x
の値をいろいろ変えて試してみよ。 -
このプログラムのフローチャートを描いてみよ。
elif
(及び else
) は それ以前の条件が成立しなかった場合のみ 実行される。
言い換えると、一度条件が成立すると、そのブロックのみ実行し、if の最後に飛ぶ。
従って次のプログラムは (文法的には問題はないが) 不適切である。
if a > 0:
...
elif a > 1:
# ここにくることはない
else:
...
条件の書き方—ブール型と比較演算子と論理演算子
ブール型 (Boolean)
これまで変数と値の型として、数値及び文字列を扱ってきたが、ここでもう一つ新しい型であるブール型について学ぼう。
ブール型 (ブーリアン Boolean, 論理型などとも言う) は、その値に真 (True
) か偽 (False
) をとるもののことを言う。
原則としてブール値を変数に格納すべきではないが、
a = True
b = False
などと使うこともできる。
ここで「型」という言葉が出てきたので、それについてちょっとだけ触れておく。 型というのは要するに変数や値の「種類」と言ってよい。
これまでに
-
数値型
-
文字列型
-
ブール型
が出てきた。 他にもあるが、まずはこれらを押さえおこう。
数値型には整数型と浮動小数点型 (と複素数型) があるが、最初のうちはそれほど意識しなくて良い。
比較演算子
演算子のうち算術演算子についてはすでに述べた。
ここでは、 if
文等で使用される 比較演算子 について説明する。
その名の通り、二つのものを比較する為に使われる演算子であり、主に以下のものが使われる。
最初の二つ以外は自明であろう。
-
a == b
-
二つの数が等しいかどうか判定する。等号が二つであることに注意 (初心者が間違えやすいポイントである)。一つだと代入になる。 値が小数の場合は注意を要するが、それについては数値計算で注意すべきことで説明する。
-
a != b
-
「
a
とb
が等しくないかどうか」を判定する -
a > b
-
「
a
がb
より大きいかどうか」を判定する -
a >= b
-
「
a
がb
以上かどうか」を判定する。=>
とは書けないので注意 -
a < b
-
「
a
がb
より小さいかどうか」を判定する -
a <= b
-
「
a
がb
以下かどうか」を判定する。=<
とは書けないので注意
これらの演算子はその結果としてブール型の値 (つまり True
または False
) を返す。
「演算子が値を返す」という言い方は違和感があるかもしれないが、要は、
1 + 2
を「計算」すると 3
という値が得られるのと同様に、 1 == 1
を「計算」すると True
という値が得られるというだけのことである。
以下のプログラムを入力し、実行してみよ。
その後、このプログラムは何を「計算」しているか考えてみよ。
また一、二行目の a
, b
の値をいろいろ変えて試してみよ。
a = 0
b = 10
result = (a == b)
print(result)
論理演算子
比較演算子だけでは「… かつ … のとき」とか「… あるいは … のとき」とか「… ではないとき」のような条件が書けない。 そこで、以下の演算子を使う。
-
and
-
… かつ …
-
or
-
… または …
-
not
-
… ではない
A or B
は A または B の「少なくとも」一方が真のときに真となる。
A と B の両方が真のときも真になる点に注意。
これらは具体的には以下のように使う。
if (a > 0) and (b > 0):
# a が 0 より大きく、かつ b が 0 より大きいとき
# (つまり a も b も 0 より大きいとき) に実行
if (a > 0) or (b > 0):
# a か b の一方または両方が 0 より大きいときに実行
if not ((a > 0) or (b > 0)):
# 「a が 0 より大きい または b が 0 より大きい」
# ではないときに実行
以下のプログラムを入力し、実行してみよ。
また一、二行目の a
, b
の値をいろいろ変えて試してみよ。
a = 0
b = 0
if (a > 0) and (b > 0):
print("a > 0 and b > 0")
if (a > 0) or (b > 0):
print("a > 0 or b > 0")
if not ((a > 0) or (b > 0)):
print("not ((a > 0) or (b > 0))")
演算子の優先順位
演算子の優先順位はちょっとややこしいので、まずは、
-
not
,and
,or
の順で優先順位が高い
だけ押さえておいて欲しい1。
例えば not a and b
は (not a) and b
と等価である (not (a and b)
ではない)。
あとは (
… )
で明示するのが良いだろう。
さらに言えば、
-
比較演算子 (
==
,>=
等) -
論理演算子 (
not
,and
,or
)
の順で優先順位が高いので、上に出てきた if (a > 0) or (b > 0):
の括弧は無くてもよい。
しかし if not ((a > 0) or (b > 0)):
の場合は if not a > 0 or b > 0:
とは書けない (なぜか考えてみよ)。
このような間違いを避けるために、無闇に括弧を省略しようとしない方が良い。
(括弧がないと、後で他の人あるいは自分がプログラムを読んだときに、意図してこうなっているのか、間違っているのかが分かりにくい。)
おさらい: if
文
ブール型について理解したところで、再度 if
について見てみよう。
これまでは「条件が成立した (しなかった) 場合」などと言ってきたが、「式の結果が真 (偽) の場合」と言う方がより正確である。
つまり if
のより正確な説明は、
if 式1:
式1が真だったときの処理
elif 式2:
(式1が偽かつ)式2が真だったときの処理
else:
どの式も真にならなかった場合
(= 全ての式が偽だった場合) の処理
となる。
通常は「条件が成立した (しなかった)」で問題ないが、その背後には真偽値があることを押さえておきたい。
まとめ
ここでは条件分岐について学んだ。
-
if
,elif
,else
で条件に応じた処理ができる -
基本形:
if 条件1: # 条件 1 成立時 elif 条件 2: # (条件 1 不成立かつ) # 条件 2 成立時 elif 条件 3: # (条件 1, 2 不成立かつ) # 条件 3 成立時 elif ... : ... else: # どの条件も成立しなかったとき
elif
,else
は必要に応じて使用する。 -
比較演算子 (
a == b
,a != b
,a > b
,a >= b
,a < b
,a <= b
) について学んだ -
論理演算子 (
not
,and
,or
) について学んだ
厳密な優先順位を知りたければ、 https://docs.python.org/3/reference/expressions.html#operator-precedence を参照のこと。