既に述べた通り、if〜else文は条件が二択(場合分けが2種類)のときには役に立つ。そうではなく、もっと複雑に条件分けをしたいときに使うのがif〜elif〜else文だ。この構文を以下に示す。
if 条件1:
条件1が成立したときに実行するブロック
elif 条件2:
条件2が成立したときに実行するブロック
else:
全ての条件が成立しなかったときに実行するブロック
「elif 条件2:」は「if 条件1:」と同じインデント位置に置き、そこからインデントを付けて「条件2が成立したときに実行するブロック」を記述するのは、if〜else文と同様だ。この複合文では、まず「条件1」が成り立つかどうかが判断される。成り立てば、if節に記述したコードが実行され、if文の実行は終了する。成り立たないときには、次に「elif節」に記した「条件2」が成り立つかどうかが判断される。成り立てば、そのelif節に記述したコードが実行され、if文の実行は終了する。条件2も成り立たないときにはelse節が実行される。
elif節は複数記述してもよい。つまり、次のような書き方もできる。
if 条件1:
条件1が成立したときに実行するブロック
elif 条件2:
条件2が成立したときに実行するブロック
elif 条件3:
条件3が成立したときに実行するブロック
…… elif節は好きなだけ記述できる ……
elif 条件n:
条件nが成立したときに実行するブロック
else:
全ての条件が成立しなかったときに実行するブロック
この場合も、「条件1」から順にそれが成り立つかどうかが判断され、いずれかの条件が成立した時点で、その節のコードが実行され、if文の実行は終了する。全ての条件が成り立たないときにだけelse節のコードが実行される。なお、else節はなくても構わない。
if 条件1:
条件1が成立したときに実行するブロック
elif 条件2:
条件2が成立したときに実行するブロック
elif 条件3:
条件3が成立したときに実行するブロック
…… elif節は好きなだけ記述できる ……
elif 条件n:
条件nが成立したときに実行するブロック
この場合には、全ての条件が成り立たなければ、何のコードも実行されないことになる。
では、「FizzBuzz問題」を解くコードを書きながら、実際にif〜elif〜else文を書いてみよう。「FizzBuzz問題」とは次のような問題だ。以下では「結果とする」というところは「画面にそれを出力する」と読み替えてほしい。
場合分けが複数あるので、これはif〜else文では表現できない。if〜elif〜else文の出番だ。「XXXが○○の倍数なら」というのは既に見た通り「XXX % ○○ == 0」で調べられる。ということは、上の条件分けは次のように書けるということだ。ここでは、先ほどと同じくユーザーから変数numberに数値を受け取り、それをFizzBuzz問題を解くコードに与えるものとしよう。
「3の倍数かつ5の倍数」の条件を言い換えると、「15の倍数」となるので、上では「number % 3 == 0」としている。実際には「3の倍数かつ5の倍数」をプログラムコードで表現することもできるが、これについては後で説明する。
これらの条件をif〜elif〜else文の各節に当てはめていけばよい。基本構造は先ほどの「偶数か奇数か」の例と同様だ。上の場合分けを素直に書いてみよう。
number = input('何か数値を入力してください: ')
number = int(number)
if number % 3 == 0:
print('Fizz')
elif number % 5 == 0:
print('Buzz')
elif number % 15 == 0:
print('FizzBuzz')
else:
print(number)
これをセルに入力して、実行してみよう。1、3、5、15をそれぞれ入力した結果を以下に示す。
「1」を入力したときには、入力した通りの「1」が表示されている。一方、「3」と「5」を入力したときには、想定通りに「Fizz」「Buzz」が表示されている。ところが、「15」を入力したときの結果が「FizzBuzz」とはなっていない。これがいわゆる「バグ」だ。理由は単純で、「15は3の倍数でもあるから、最初のif節が実行されたところで、条件が成立してif文が終了してしまう」ことだ。つまり、以下のように「3の倍数かつ5の倍数」であることを最初に判定する必要があるということだ。
number = input('何か数値を入力してください: ')
number = int(number)
if number % 15 == 0:
print('FizzBuzz')
elif number % 3 == 0:
print('Fizz')
elif number % 5 == 0:
print('Buzz')
else:
print(number)
このコードを実行すると、想定通りの動作をしてくれる。
このように、if文で場合分けを記述するときには、その順序にも気を付ける必要があることは覚えておこう。よく言われることだが、「プログラムは思った通りに動作するのではなく、書いた通りに動作する」のである。
if文についての説明はだいたい終わったが、最後にif文に記述する「条件」について少し詳しく見ておこう。
ここまでif文は「条件に応じて、処理を分岐させる」と述べ、その「条件」には「==」演算子を使って「変数numberの値が〇〇の倍数か」などを記述していた。
ここで使用していた「==」演算子はPythonの「比較演算子」と呼ばれるものの一つだ。これは演算子の左右に置いた2つの被演算子が等しいかどうかを調べる。等しければ、その結果は「True」となる。等しくなければ、その結果は「False」となる。TrueとFalseはPythonのbool型の値(オブジェクト)であり、何らかの条件が成り立っているかどうかを示すために使われる。日本語ではTrueのことを「真」と、Falseのことを「偽」と呼ぶ。また、これらをまとめて「真偽値」と呼ぶこともある。
if文の「条件」の部分には、「真偽値を返す値や式」を記述する必要がある。実際に、「==」演算子で「7が2の倍数かどうか」と「6が2の倍数かどうか」を調べて、その値がどうなるかを見てみよう。これにはセルに「print(7 % 2 == 0)」「print(6 % 2 == 0)」と入力して実行すればよい。
上の画像の通り、「==」演算子による演算の結果はTrueかFalseになることが分かったはずだ。if文は「条件に記述した式がTrueなら〇〇を、Falseなら××を」のように処理を分岐させているということだ。
2つの値を比較するための演算子には、「==」演算子に加えて以下のようなものがある。
比較演算子 | 意味 |
---|---|
> | (左側の被演算子が右側の被演算子)より大きい |
< | (左側の被演算子が右側の被演算子)より小さい |
>= | (左側の被演算子が右側の被演算子)以上 |
<= | (左側の被演算子が右側の被演算子)以下 |
== | (左側の被演算子と右側の被演算子が)等しい |
!= | (左側の被演算子と右側の被演算子が)等しくない |
Pythonの比較演算子(一部) |
これらの比較演算子とif文などを組み合わせることで、さまざまな状況に応じて、さまざまな処理を書けるようになる。
if文の「条件」にはさらに複雑な式を書くこともできる。例えば、先ほどは「number % 15 == 0」としてしまった部分がそうだ。もともとは「変数numberの値が3の倍数かつ5の倍数」が条件だったのを、「要するに変数numberの値が15の倍数」とまとめてしまったが、これは「and」演算子を使うことで「number % 3 == 0 and number % 5 == 0」のように書ける。「and」演算子は、「ブール演算子」や「論理演算子」と呼ばれるものの1つで「条件1かつ条件2」の「かつ」を表すものだ。ブール演算子を使った演算の結果は、比較演算子と同様、真偽値となる。
「and」演算子を使うと、先ほどのコードは次のようになる。
number = input('何か数値を入力してください: ')
number = int(number)
if number % 3 == 0 and number % 5 == 0:
print('FizzBuzz')
elif number % 3 == 0:
print('Fizz')
elif number % 5 == 0:
print('Buzz')
else:
print(number)
何かの処理を行うための条件が複数ある場合には、and演算子でそれらの条件を繋げて書くようにしよう。
ブール演算子としては、この他に「または」を意味する「or」演算子、「条件の否定」を意味する「not」演算子がある。「not」演算子は「単項演算子」で、「not 条件」のような書き方をする。
演算子 | 説明 | 例 |
---|---|---|
and | 複数の条件が全て成立するかどうかを調べる | number % 3 == 0 and number % 5 == 0 (変数numberの値が3の倍数かつ5の倍数) |
or | 複数の条件のいずれかが成立するかどうかを調べる | number < 1 or 100 < number (変数numberの値が1より小さいか、100より大きい。特定の範囲の値だけを受け付けつける場合) |
not | 条件がTrueなら演算結果はFalseになり、条件がFalseなら演算結果はTrueになる | not True(演算結果はFalse) |
ブール演算子 |
実は、ここまで「if文の条件には真偽値を返す値や式を書く」と述べてきたが、実際には数値や文字列などを書いてもよい。if文の条件を評価する(TrueになるかFalseになるかを調べる)ときに、数値や文字列などはその実際に値に応じて、TrueかFalseのいずれかの値と見なされる(リストなどのデータ構造についてはまだきちんと紹介していないが、ここで述べておく)。
例えば、先ほどまでは「変数numberの値が3の倍数かどうか」を調べるのに「number % 3 == 0」と書いていた。「変数numberの値が3の倍数」であれば「number % 3」の値は「0」となる。「0」はFalseと見なされるが、not演算子で条件を否定する、つまり「not number % 3」と書けば、これは「変数numberの値が3の倍数のとき」には「True」となる。このことを使うと、先ほどのコードは次のように書けるということだ。
number = input('何か数値を入力してください: ')
number = int(number)
if not number % 3 and not number % 5:
print('FizzBuzz')
elif not number % 3:
print('Fizz')
elif not number % 5:
print('Buzz')
else:
print(number)
これがプログラマーの意図がきちんと反映されたコードであるかどうかの判断は難しい。素直に「==」演算子を使った書き方をすべきだとも思うが、このような書き方もできることは覚えておこう。
比較演算子とブール演算子については第11回でも触れる。実際に使って、身に着けていこう。
Copyright© Digital Advantage Corp. All Rights Reserved.