条件を見張りながら繰り返すwhileループ
forが決まったシーケンスを順に回すのに対して、whileは条件がTrueである限りループを続けます。何回繰り返せばいいか事前にわからないときの定番です。たとえば、成功するまでリトライし続けたい、ユーザーが「やめる」と言うまで入力を受け付けたい、サービスが応答するまでポーリングしたい、といった場面ですね。
基本の形はとてもシンプルです。
これで 0 から 4 までが出力されます。Python は繰り返しのたびに先頭で条件をチェックします。条件が真なら本体を実行し、またチェックに戻る。条件が偽になった時点でループを抜けます。
ここで大事なのが count += 1 の存在です。これを書き忘れると条件がずっと真のままになり、いわゆる 無限ループ に陥ります。これが while の一番の落とし穴で、書けるなら for を優先したほうがいい理由でもあります。
while ループが活きる場面
典型的な使いどころをいくつか挙げてみます。
成功するまでリトライする。
ユーザーが終了するまで入力を読み取り続ける。
キューを処理する。
共通しているのは、要素を順番に処理するのではなく、状態の変化を待ち受けているという点です。
while True は普通に使ってOK
次のようなパターンはよく見かけます。
これは、ループを抜ける本当の条件がループ本体の内側にあって、先頭できれいに判定できないときの定番の書き方です。should_continue みたいなフラグを用意して、片方で更新して別の場所でチェックする…なんてやり方より、ずっと読みやすくなります。
守るべきルールはひとつだけ。必ず break(あるいは return や例外)でループを抜ける経路を用意しておくこと。抜け道のない while True: は、プログラムをフリーズさせる典型パターンです。
無限ループを避けるには
無限ループが起きるのは、条件がずっと真のままになってしまうときです。よくある原因はこのあたり:
- 変数を更新し忘れている。
while count < 5:と書いたら、ループ本体のどこかでcountを変化させる処理が必要です。 - 違う変数を更新している。
while i < 10:なのに、ループ内でj += 1している — 変数が多くなってくると見落としがちです。 - 浮動小数点数の比較。
while x != 1.0:は、xが 1.0 に 近づく だけで一致しない場合、永遠に回り続けます。代わりに<=やabs(x - 1.0) < toleranceを使いましょう。
もしターミナルで無限ループにハマってしまったら、Ctrl+C を押してください。割り込みシグナルが送られて、Python は実行を止めてくれます。
break、continue、else でループを制御する
while には、for と同じ 3 つの制御ツールが使えます:
breakはループを即座に抜けます。continueは次のイテレーションへ飛ばします(つまり条件が再チェックされます)。elseは、ループがbreakされずに 最後まで終わった場合に実行されます。
これは素数判定の原始的な実装です。内側の break が走った時点でその数は合成数。ループが条件成立で自然に終了した場合は else ブロックが動き、素数だと判定されます。
while と for の使い分け
頭の中でサッと判断するコツはこんな感じです。
- 手元にコレクション(リストなど)があって、それを順に処理したい? →
for - 決まった回数だけ繰り返したい? →
for i in range(n): - ある条件が変わるまで回し続けたい? →
while
Python を書き始めたばかりのころは、ループの9割方は for で片付くことに気づくはずです。while の出番は、ポーリング処理やリトライ処理、簡易的な REPL を組むときなど。もしインデックスを使ってリストを回すために while を使っているなら、それは for + enumerate に書き換えるべきサインです。
while ループの実用例
数当てゲームは while の定番サンプルです。プレイヤーの当て方によって繰り返し回数が変わるので、ちょうど while が活きる場面なんです。
何回でループが終わるかは事前にはわからない ― ユーザーの入力次第だからです。まさにこういうときのために while が存在します。
次のステップ
これで Python が用意している 2 種類のループを一通り見てきました。次は range() を掘り下げていきます。カウント系の for ループではほぼ必ず登場する関数なので、コレクションの話題に入る前に細かい挙動まで押さえておきましょう。
よくある質問
forループではなくwhileループを使うのはどんなとき?
繰り返す回数が事前に分からないときはwhileの出番です。たとえば「成功するまでリトライする」「ユーザーが 'quit' と入力するまで読み込み続ける」といったケースですね。一方、リストなど決まったコレクションを順に処理するならforの方が自然です。
Pythonで無限ループを避けるにはどうすればいい?
ループの中で、条件式がいずれFalseになるように値を更新することが大事です。無限ループの原因で一番多いのは、条件に使っている変数の更新を忘れているパターン。もし実行中にハマってしまったら、ターミナルで Ctrl+C を押せば強制終了できます。
while Trueって使っても大丈夫?アンチパターンじゃない?
while Trueって使っても大丈夫?アンチパターンじゃない?結論から言うと、全然問題ありません。while True:の中に明確なbreakを書くのは「特定の条件で抜ける」処理を書く際の定番パターンです。わざわざフラグ用のbool変数を用意して2箇所で管理するより、むしろこっちの方がスッキリ読めます。