Pythonで繰り返し処理を記述するためのもう1つの機構である「while文」を見ていこう。while文をfor文で書き換えたり、少し複雑なプログラムも作ったりしよう。Python 3.8以降で使える代入式とwhile文の組み合わせについても紹介する。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
* 本稿は2019年5月14日、2022年6月3日に公開/改訂された記事を、Python 3.12.0で動作確認したものです(確認日:2023年10月16日)。
前回はPythonで繰り返し処理を行うための制御構造の一つである「for文」を取り上げた。今回は、繰り返し処理を行うためのもう一つの構文である「while文」を紹介しよう。
前回紹介したfor文は「文字列やリストなど、反復可能なオブジェクトを与えると、その要素を1つずつ取り出しながら処理を繰り返し実行する」ものだったが、while文は「何かの条件が成立している間、処理を繰り返す」ためのものだ。例えば、「ユーザーが入力した数値が当たりの数値と同じではない間」などがその「条件」となる。
while文の構文は次のようになる。
while 条件:
ブロック
「while」に続けて「その下のブロックを繰り返し実行するための条件」を記述する。ブロックはfor文で見たブロックと同様だ(半角空白文字かタブ文字でインデントを付けて表現する)。whileと条件の後にはコロン(:)を付けるのを忘れないようにしよう。多くの場合、while文で繰り返し処理を行う部分では、条件判定に使用する変数の値などを変更することで、次の条件判定の際に繰り返し処理を継続するか、while文を終了するかが決定される。
ここで「条件」とは、次の2つの値で示される。
「条件」には前回の「if文の条件と比較演算子とブール演算子」で説明したのと同じ、真偽値を返す式を記述する。while文はまず「条件が真かどうか」を判断して、真であればブロックに書かれた処理を実行し、処理が終わると「条件が真かどうか」を再度判断する。条件が真である間はこれを繰り返して、条件が偽になったところで、while文の実行は終了する。
例としてwhile文を使って、「10」「9」……「2」「1」とカウントダウンをしていき、最後に爆発する(「Bomb!」とメッセージを表示する)プログラムを考えてみよう。まず、これにはカウントダウンする値を保存しておく変数が必要になる。ここでは「counter」という名前にしておこう。その初期値は10だ。
counter = 10
プログラムの動作を考えると「条件」は「変数counterの値が0より大きい間」となる。「ブロック」で実行する内容は「変数counterの値を表示してから、その値を1減らす」となる。これを表に示すと次のようになる。
変数counterの値 | 変数counterの値が0より大きいか | while文のブロックで行うこと |
---|---|---|
10 | True(真) | 10を表示して、変数counterの値を1減算 |
9 | True(真) | 9を表示して、変数counterの値を1減算 |
… | … | … |
2 | True(真) | 2を表示して、変数counterの値を1減算 |
1 | True(真) | 1を表示して、変数counterの値を1減算 |
0 | False(偽) | ループを抜ける |
このプログラムで行いたい処理 |
では、「条件」をPythonのコードでどうやって表現すればよいだろう。これには前回にも登場した「比較演算子」と呼ばれる演算子を使用する。ここで使用するのは数値の大小を比較する「>」演算子だ。
比較演算子 | 意味 |
---|---|
> | (左側の被演算子が右側の被演算子)より大きい |
< | (左側の被演算子が右側の被演算子)より小さい |
>= | (左側の被演算子が右側の被演算子)以上 |
<= | (左側の被演算子が右側の被演算子)以下 |
== | (左側の被演算子と右側の被演算子が)等しい |
!= | (左側の被演算子と右側の被演算子が)等しくない |
Pythonの比較演算子(一部。再掲) |
「>」演算子を使うと、「変数counterの値が0より大きい」は「counter > 0」と書ける(「<」演算子を使って「0 < counter」としてもよい)。「>」は比較演算子の一つで、その演算子の左側にある値が、右側にある値より大きければ、その式(counter > 0)の値が真(True)となる。左側の値が右側の値と等しいか、小さくなればその式の値は偽(False)となる。
よって、このプログラムは次のようになる。
counter = 10
while counter > 0:
ブロック
残るブロックには、インデントを揃えて、counterの値を表示する行と、counterの値を1減らす行を書けばよい。
counter = 10
while counter > 0:
print(counter)
counter = counter - 1 # counter -= 1 でも同等
ブロックの1行目は、既におなじみのprint関数呼び出しだ。引数には変数counterを渡しているので、その値がそのまま画面に表示される。次の行は変数counterに「変数counterから1を減らした数」を代入する。Pythonにおいては「=」演算子は、数学のような「変数counterの値と、変数counterから1を減らした値が等しい」を意味するのではなく、あくまでも、左辺に「新しい値を代入」するための演算子であることを覚えておこう*1。
*1 「counter = counter - 1」行は、第4回「変数とは」の「累算代入演算子」で紹介した累算代入演算子の一つである「-=」演算子を使って、「counter -= 1」と書いてもよい。
このコードをセルに書いて、実行するとその結果は次のようになる。
プログラムの動作に1つ足りない点があることに気付いたはずだ。それは最後に「Bomb!」と表示することだ。このコードを付け足して、以下のようにすればこのプログラムは完成だ。
counter = 10
while counter > 0:
print(counter)
counter = counter - 1
print('Bomb!')
最後の行は、インデントがwhile文の先頭行と同じなので、while文で繰り返し実行するブロックには含まれていないことに注目しよう。つまり、このprint関数呼び出しはwhile文での繰り返しが終わった後で実行される。よって、実行結果は次のようになる。
繰り返し処理を行うwhile文の基本は以上の通りだ。
if文やfor文と同様に、while文にもelse節がある。
while 条件:
ブロック
else:
条件が偽となったときに実行するブロック
while文のelse節は「条件」が偽になると実行される。つまり、while文で行う繰り返し処理が終了したら実行される処理をここに書ける(for文のelse節と同じだ)。そのため、else節を使うと、先ほどのコードは次のように書き直せる(実行結果は省略)。
counter = 10
while counter > 0:
print(counter)
counter = counter - 1
else:
print('Bomb!')
このコードでは、変数counterの値が0になり、while節で条件が成り立たなくなった時点で繰り返し処理が終わって、else節のコードが実行される。
for文と同様、else節に書いたコードをwhile文の下に書いた場合、その動作は変わらないこともあれば、変わることもある。これについては前回の「break文」で見た通りだ。
前回の「for文とrange関数による繰り返し処理」ではrange関数を紹介したが、これにはもう一つの構文がある。これを使うと、while文を使って書いた「カウントダウン」プログラムをfor文で書き直せる。そのrange関数の構文は次の通りだ。
range(start, stop, step)
この形式のrange関数は第1引数(start)と第2引数(stop)で示される範囲(ただし、stopの値は除く)にある数値を反復してくれる。このときに第3引数に指定した値が反復時に加算される差分となる(step省略時には「1」と見なされるので、通常は1ずつ値が増えていく)。シンプルな方のrange関数を「range(10)」として呼び出すのは、この形式のrange関数を「range(0, 10, 1)」を指定して呼び出すのと同じ意味になる。例えば、0〜10の間の偶数を数え上げたければ、次のようなコードを書ける。
for number in range(0, 11, 2):
print(number)
今見た形式のrange関数ではそれぞれの引数に正の値(および0)だけではなく、負の値も渡せる。例えば、第3引数(step)に「-1」を渡せば、初期値からストップ値へとカウントダウンが行えるわけだ。例えば、range関数に渡す引数をそれぞれ「10」「0」「-1」とすれば、10から1まで、差分を-1としてカウントダウンが行える。そこで、先ほどのwhile文を使ったコードは次のように書き換えられる(else節を使ってもよい。興味のある方は試してみてほしい)。
for number in range(10, 0, -1):
print(number)
print('bomb!')
while文を使ったコードをfor文で書き換える、あるいはその逆は常にできるとは限らないが、Pythonに少し慣れてきたら、それまでに自分で書いたコードを見直して、練習がてら書き直せるかどうかを試してみてもよいだろう。
Copyright© Digital Advantage Corp. All Rights Reserved.