[Python入門]#14 while文基礎 – 無限ループを回避せよ

今回は制御構文のラストである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+CCommandと間違えないように!)

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の違いをきちんと把握しておくことで、ループ処理の可能性が大きく広がるはずです。

タイトルとURLをコピーしました