今回は制御構文のラストであるwhile文の基本構文と、continue/break文の記述、使用方法についてお話します。
while文の書き方 基本構文
それではwhile文の基本構文をチェックしていきましょう。
x = 5
while x>0:
print(x)
x -= 1
print("アクション!")
#5
#4
#3
#2
#1
#アクション!
while 条件式:
がwhile文のヘッダです。while文はこの条件式の結果がTrueのとき、下の処理が実行されます。毎度のことですが、処理内容の部分ではインデントが必須です。忘れないようにしましょう。
上のコードでは変数xを「カウンタ」として使用し、処理の中でマイナス1(デクリメント)しています。これによってループする度にxの値は小さくなり、6回目のループでは「x>0」の結果はFalseとなります。
条件式がFalseになるとwhile文は終了し、処理は次の行へ移ります。
無限ループの発生
while文の条件式は基本的に「いつかはFalse」にならなければなりません。そうでなければ、このループは永遠に繰り返されることになります。(いわゆる無限ループです)
一度無限ループを体験してみましょう。上のコードの「x-=1」を削除すると、xはずっと5のままです。そのため、while文は永遠に「5」をコンソール出力し続けることになります。
x = 5
while x>0:
print(x)
print("アクション!")
見た目は動いていないように見えますが実は高速に「5」が出力されています。こうなったらこの処理を強制終了するしかありません。Ctrl+Cでコードを強制終了できます。(Macの場合はControl+C。Commandと間違えないように!)
KeyboardInterrupt例外が送出され、処理は中断されます。
break文でループを抜け出す
while文の条件式は基本的にいつかはFalseにならなければなりません。しかし、それが「全て」ではありません。こんなwhile文も普通に使われます。
while True:
処理内容
このwhile文のヘッダは一見すると無限ループへの片道切符です。しかしこの後の処理内容で「break」を仕込むことによって、ループを続けるかどうかの判断を処理側に委ねることができます。例を見てみましょう。
import random
while True:
num = random.randint(0,10)
print(num)
if num == 10:
break
1行目ではrandomモジュールをインポートしています。
randomモジュールはランダムな数値、いわゆる乱数を出力するモジュールです。ここではwhile文の処理の始めにrandomモジュールのrandint
メソッドを使用し、0~10の整数をランダムに出力し、次の行でそれをコンソール出力します。
最後の2行に注目してください。ここではif文で「numが10のとき(randint
メソッドが10を出力したとき)、breakします」というのがその内容です。
「break」と記述するだけで、Pythonでは「そのループを終了する」という意味になります。つまりこの場合、breakが実行される=while文の終了になります。
ではコードを実行してみましょう。実行結果はこのようになります。
#5
#3
#1
#3
#8
#...
#10
乱数を使用しているため、何回ループが回されるかはランダムですが、最後は必ず「10」で終わるはずです。
continue文で処理をスキップする
もう1つ、処理をスキップするcontinue文もご紹介しておきます。break文とペアで使用されることも多いcontinue文は、ループを抜けることはありません。ただ指定した条件に合致してcontinueが実行された時、その回のループ処理のみ処理がスキップされます。
先ほどのコードをアレンジして確かめてみましょう。
import random
while True:
num = random.randint(0,10)
if num == 10:
continue #numが10ならcontinue
elif num == 0:
print(num)
break #numが0ならprintしてbreak
print(num) #ifに引っかからなければprint
#6
#4
#9
#6
#0
今回のコードは実行結果に「10」が表示されず、必ず「0」で終わることが確認できます。処理的にははループの中に設置されたif-elif文で、2ヶ所の検問を作っているようなものです。
最初に「6」が出力されています。6はif文の検問に引っかかること無く、そのままprintされます。
次に「10」が出力されたとします。10もそのまま進もうとしますが、ifの検問に引っかかります。
「10」を補足したif文の中にあるのは「continue」のみです。continueは特に何をするというわけではありません。ただループ処理のヘッダに「次のループ」を要求するだけです。
哀れな「10」はprintされることなく、忘れ去られてしまいます。
最後にbreakもおさらいしておきましょう。randint
メソッドが「0」を出力した場合、ifには引っかかりませんがその後のelif文に捕捉されます。
捕捉された「0」はelif文に記述された処理に回され、printされます。その直後breakにより「ループ終了」が宣言され、while文が終了します。
continueとbreakの違いをきちんと把握しておくことで、ループ処理の可能性が大きく広がるはずです。