[Python入門]if文による条件分岐Python入門(2/3 ページ)

» 2023年09月11日 05時00分 公開
[かわさきしんじDeep Insider編集部]

if〜elif〜else文

 既に述べた通り、if〜else文は条件が二択(場合分けが2種類)のときには役に立つ。そうではなく、もっと複雑に条件分けをしたいときに使うのがif〜elif〜else文だ。この構文を以下に示す。

if 条件1:
    条件1が成立したときに実行するブロック
elif 条件2:
    条件2が成立したときに実行するブロック
else:
    全ての条件が成立しなかったときに実行するブロック

if〜elif〜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:
    全ての条件が成立しなかったときに実行するブロック

elif節は必要なだけ記述できる

 この場合も、「条件1」から順にそれが成り立つかどうかが判断され、いずれかの条件が成立した時点で、その節のコードが実行され、if文の実行は終了する。全ての条件が成り立たないときにだけelse節のコードが実行される。なお、else節はなくても構わない。

if 条件1:
    条件1が成立したときに実行するブロック
elif 条件2:
    条件2が成立したときに実行するブロック
elif 条件3:
    条件3が成立したときに実行するブロック
…… elif節は好きなだけ記述できる ……
elif 条件n:
    条件nが成立したときに実行するブロック

else節がないと、全ての条件が成り立たなければ、if文のコードは何も実行されない

 この場合には、全ての条件が成り立たなければ、何のコードも実行されないことになる。

 では、「FizzBuzz問題」を解くコードを書きながら、実際にif〜elif〜else文を書いてみよう。「FizzBuzz問題」とは次のような問題だ。以下では「結果とする」というところは「画面にそれを出力する」と読み替えてほしい。

  • 与えられた数値が3の倍数なら「Fizz」を結果とする
  • 与えられた数値が5の倍数なら「Buzz」を結果とする
  • 与えられた数値が3の倍数かつ5の倍数なら「FizzBuzz」を結果とする
  • それ以外のときには、与えられた数値を結果とする

 場合分けが複数あるので、これはif〜else文では表現できない。if〜elif〜else文の出番だ。「XXXが○○の倍数なら」というのは既に見た通り「XXX % ○○ == 0」で調べられる。ということは、上の条件分けは次のように書けるということだ。ここでは、先ほどと同じくユーザーから変数numberに数値を受け取り、それをFizzBuzz問題を解くコードに与えるものとしよう。

  • 3の倍数:number % 3 == 0
  • 5の倍数:number % 5 == 0
  • 3の倍数かつ5の倍数:number % 15 == 0
  • それ以外:else節

 「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)

FizzBuzz問題を解くプログラム(最初のバージョン)

 これをセルに入力して、実行してみよう。1、3、5、15をそれぞれ入力した結果を以下に示す。

プログラムの実行結果。15を入力したときの結果が期待と異なっている プログラムの実行結果。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)

修正後のプログラム

 このコードを実行すると、想定通りの動作をしてくれる。

「15」と入力すると「FizzBuzz」と表示された 「15」と入力すると「FizzBuzz」と表示された

 このように、if文で場合分けを記述するときには、その順序にも気を付ける必要があることは覚えておこう。よく言われることだが、「プログラムは思った通りに動作するのではなく、書いた通りに動作する」のである。

 if文についての説明はだいたい終わったが、最後にif文に記述する「条件」について少し詳しく見ておこう。

if文の条件と比較演算子とブール演算子

 ここまでif文は「条件に応じて、処理を分岐させる」と述べ、その「条件」には「==」演算子を使って「変数numberの値が〇〇の倍数か」などを記述していた。

 ここで使用していた「==」演算子はPythonの「比較演算子」と呼ばれるものの一つだ。これは演算子の左右に置いた2つの被演算子が等しいかどうかを調べる。等しければ、その結果は「True」となる。等しくなければ、その結果は「False」となる。TrueとFalseはPythonのbool型の値(オブジェクト)であり、何らかの条件が成り立っているかどうかを示すために使われる。日本語ではTrueのことを「真」と、Falseのことを「偽」と呼ぶ。また、これらをまとめて「真偽値」と呼ぶこともある。

  • True(真):条件が成り立っていることを意味する
  • False(偽):条件が成り立っていないことを意味する

 if文の「条件」の部分には、「真偽値を返す値や式」を記述する必要がある。実際に、「==」演算子で「7が2の倍数かどうか」と「6が2の倍数かどうか」を調べて、その値がどうなるかを見てみよう。これにはセルに「print(7 % 2 == 0)」「print(6 % 2 == 0)」と入力して実行すればよい。

「==」演算子を使った演算の結果はTrueかFalseになる 「==」演算子を使った演算の結果はTrueかFalseになる

 上の画像の通り、「==」演算子による演算の結果は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演算子を使って書き直したコード

 何かの処理を行うための条件が複数ある場合には、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のいずれかの値と見なされる(リストなどのデータ構造についてはまだきちんと紹介していないが、ここで述べておく)。

  • 数値:0(0.0)はFalseと見なされる。それ以外はTrueと見なされる
  • 文字列:空文字列('')はFalseと見なされる。それ以外はTrueと見なされる
  • リストなど:要素がなければ(空のリストなど)Falseと見なされる。それ以外はTrueと見なされる

 例えば、先ほどまでは「変数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)

not演算子を使って書き直したコード

 これがプログラマーの意図がきちんと反映されたコードであるかどうかの判断は難しい。素直に「==」演算子を使った書き方をすべきだとも思うが、このような書き方もできることは覚えておこう。

 比較演算子とブール演算子については第11回でも触れる。実際に使って、身に着けていこう。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。