ループの途中で「止める」か「飛ばす」かは、処理の正確さとコードの読みやすさに直結します。
Pythonのbreak
とcontinue
を正しく使い分けることで、無駄な計算を避け、エラーも未然に防げます。
本記事では初心者でも迷わないように、for/whileそれぞれの基本から実践パターンまで丁寧に解説します。
Pythonのbreak/continue入門
何が違う?breakとcontinue
break
は「そのループ自体を即終了」、continue
は「今回の1回分だけスキップして次の周回へ」送ります。
どちらもループ中の分岐で使うキーワードですが、影響範囲が異なります。
ここを勘違いすると、思ったより早く終わったり、逆に余計に回ってしまいます。
「抜ける」のか「飛ばす」のかを常に意識すると混乱しにくくなります。
以下の表に動作の違いを整理します。
キーワード | 動作 | 影響範囲 | 主な用途 |
---|---|---|---|
break | ループから即座に抜ける | いちばん内側のループ | 最初の一致で探索終了、安全に無限ループを止める |
continue | 今回の周回をスキップし次へ | 現在のループの1回分 | 不正データを飛ばす、早期スキップでネスト削減 |
注意: break
もcontinue
も「いちばん内側」のループにだけ効きます。
外側のループまで一気に止めるわけではありません。
最小の例で見比べる
# break は「完全に抜ける」
for i in range(5):
if i == 3:
break # i が 3 になったらループ終了
print(i, end=" ")
print() # 改行
# continue は「今回だけ飛ばす」
for i in range(5):
if i == 3:
continue # i == 3 の周回だけスキップ
print(i, end=" ")
print()
0 1 2
0 1 2 4
forとwhileでの基本動作
for でも while でも、break
/continue
の意味は同じです。
違いはループの「回し方」で、for は反復可能な要素を順に処理し、while は条件が成り立つ間回り続けます。
状況に応じてどちらでも安全に使えます。
for での基本
# 1〜10 のうち、5が出たら打ち切る
for n in range(1, 11):
if n == 5:
print("hit 5 -> break")
break
print("n =", n)
n = 1
n = 2
n = 3
n = 4
hit 5 -> break
while での基本
# 0 から数えて 3 をスキップし、5 で終了
i = 0
while True: # 条件は True。明示的に break で抜ける
i += 1
if i == 3:
continue # 3 のときだけ処理を飛ばす
if i == 5:
break # 5 でループ終了
print("i =", i)
i = 1
i = 2
i = 4
ネスト時の注意(1段だけ抜ける)
ネスト(入れ子)したループでは、break
もcontinue
も「今いる階層(いちばん内側)」にしか効きません。
外側まで抜けたい場合は、フラグを使って外側でもbreak
するなどの工夫が必要です。
「一発で全部抜ける」とは思わないようにしましょう。
例: 内側だけ止まる
for y in range(2):
for x in range(3):
if x == 1:
print(f"inner break at y={y}, x={x}")
break # ここで止まるのは内側(for x)だけ
print(f"({y}, {x})")
print(f"after inner at y={y}") # 外側はまだ続く
(0, 0)
inner break at y=0, x=1
after inner at y=0
(1, 0)
inner break at y=1, x=1
after inner at y=1
使いどころの考え方(初心者向け)
「この先の処理は絶対に要らない」と確信できるときはbreak
、「この1個だけ不正だから飛ばしたい」ならcontinue
が目安です。
読みやすさを保つため、深いネストが生まれそうなら早期continue
で手前で帰すのも有効です。
逆に、ループの終了条件を外で管理しづらいときはwhile True
とbreak
の組み合わせがシンプルで安全です。
breakの使い方(エラー回避に効く)
無限ループ/想定外入力を止める
ユーザー入力の監視や常駐処理ではwhile True
とbreak
で「抜け道」を作っておくと暴走を防げます。
例えば、数値以外が入力されたら終了する簡易カウンタです。
入力ループを安全に停止
# 数値を足し続け、数値でない文字(例: q)が来たら安全に終了する
total = 0
while True:
s = input("数値を入力(qで終了): ")
if not s.isdigit(): # 想定外入力をガード
print("数値でない入力を検知 -> break で終了")
break
total += int(s)
print("現在の合計:", total)
print("最終合計:", total)
数値を入力(qで終了): 10
現在の合計: 10
数値を入力(qで終了): 5
現在の合計: 15
数値を入力(qで終了): q
数値でない入力を検知 -> break で終了
最終合計: 15
例外処理を使わずとも、入力の妥当性を先に判定してbreak
すれば、簡易なエラー回避が可能です。
最初の一致で探索を終了(for)
探索処理では「見つかったら終わり」にするだけで大幅に無駄が減ります。
以下は最初に見つかった偶数で探索を打ち切る例です。
# 最初の偶数を見つけたら探索終了
nums = [7, 11, 9, 4, 6, 8]
found_even = None
for n in nums:
if n % 2 == 0:
found_even = n
print("Found:", n)
break # ここでループを打ち切る
print("結果:", found_even)
Found: 4
結果: 4
ヒット後の残り要素に価値がないと分かっていれば、break
は最適化にも安全性にも効きます。
条件が満たせない時は早めに終了(while)
while で繰り返している途中に「以降は不成立」と分かったら即座にbreak
するのが正解です。
例えば割引計算で、残高が先に尽きたら処理を止めます。
# 残高から割引額を順に差し引く。残高が足りなくなったら終了。
balance = 100
discounts = [15, 10, 20, 70, 5]
i = 0
while i < len(discounts):
d = discounts[i]
if balance - d < 0:
print("残高不足 -> break")
break
balance -= d
print(f"{d} を適用。残高 = {balance}")
i += 1
print("処理終了。最終残高:", balance)
15 を適用。残高 = 85
10 を適用。残高 = 75
20 を適用。残高 = 55
残高不足 -> break
処理終了。最終残高: 55
無理な計算の前に止めることで、エラーや不整合を避けます。
ガード条件で余計な処理をしない
「やってはいけない条件」を先に判定してbreak
するのがガード条件の基本です。
深いネストを避け、無駄な処理も回避できます。
# ログを順に処理。サイズが閾値を超えたら危険なので即終了。
logs = [120, 180, 95, 310, 130] # 単位はKBと仮定
THRESHOLD = 300
for size in logs:
if size > THRESHOLD: # ガード条件
print("異常サイズを検知 -> break")
break
print(f"正常ログ({size}KB)を処理")
print("監視を終了")
正常ログ(120KB)を処理
正常ログ(180KB)を処理
正常ログ(95KB)を処理
異常サイズを検知 -> break
監視を終了
「ガードは先、重い処理は後」が読みやすさと安全性の両立ポイントです。
continueの使い方(スキップで安全に)
不正データ/空文字はスキップ
欠損や空行はcontinue
で即スキップし、正常系だけをシンプルに保ちます。
結果としてネストが浅くなり、読みやすいコードになります。
# 空文字や空白だけの行は飛ばし、残りだけ処理
lines = ["Alice", " ", "", "Bob", " Carol "]
cleaned = []
for line in lines:
s = line.strip()
if s == "": # 不正(空)データを早期スキップ
continue
cleaned.append(s)
print("受理:", s)
print("クリーンな結果:", cleaned)
受理: Alice
受理: Bob
受理: Carol
クリーンな結果: ['Alice', 'Bob', 'Carol']
0除算を避けるなら分母0はcontinue
分母が0になり得る計算はcontinue
で飛ばすだけで、ZeroDivisionErrorを確実に回避できます。
# 分子/分母のペアから比率を計算。分母0は安全にスキップ。
pairs = [(10, 2), (5, 0), (9, 3)]
ratios = []
for num, den in pairs:
if den == 0:
print("分母0を検知 -> continue")
continue
ratios.append(num / den)
print(f"{num}/{den} = {num/den}")
print("計算結果:", ratios)
10/2 = 5.0
分母0を検知 -> continue
9/3 = 3.0
計算結果: [5.0, 3.0]
入力を変えられない場面こそ、早期スキップが強力です。
ネストを浅くする早期スキップ
複数の条件を順にふるい落としてcontinue
することで、深い入れ子のif
を避けられます。
# 文字列を検査して、要件を満たすものだけ重い処理に回す
candidates = ["OK-123", "", "NG", "OK-XYZ", " "]
for s in candidates:
s = s.strip()
if s == "":
continue # 空は除外
if not s.startswith("OK-"):
continue # 接頭辞が違うものも除外
# ここに来るのは「空でない かつ 'OK-'で始まる」ものだけ
print("重い処理へ:", s)
重い処理へ: OK-123
重い処理へ: OK-XYZ
「否定条件を先に弾く」と、メイン処理は素直な一本道になります。
フィルタ処理の基本パターン(for)
for とcontinue
はシンプルなフィルタに最適です。
例えば正の偶数だけを集める処理です。
# 正の偶数だけ抽出
data = [-2, -1, 0, 1, 2, 3, 4, 5]
picked = []
for x in data:
if x <= 0:
continue # 非正の値はスキップ
if x % 2 != 0:
continue # 奇数はスキップ
picked.append(x)
print("追加:", x)
print("抽出結果:", picked)
追加: 2
追加: 4
抽出結果: [2, 4]
単純な条件の足し算なら、continue
で十分に読みやすく書けます。
実践パターン(for/while)
for+breakの定番(検索/途中終了)
検索は「見つけたら即終了」が鉄則です。
最初の一致だけが欲しいケースで威力を発揮します。
# リストから最初の3の倍数を返し、なければ None
def find_first_multiple_of_3(seq):
for v in seq:
if v % 3 == 0:
print("hit:", v)
return v # 関数なら return も即終了。for-else より分かりやすい
return None
nums = [5, 7, 10, 12, 14]
ans = find_first_multiple_of_3(nums)
print("答え:", ans)
hit: 12
答え: 12
関数内ではbreak
の代わりにreturn
で早期終了するのも読みやすい選択です。
for+continueの定番(条件付き処理)
「条件を満たさない要素は飛ばす」前提で本筋だけを書くと、処理の見通しがよくなります。
# 商品リストから、在庫あり かつ 有効価格だけを集計
items = [
{"name": "A", "price": 120, "stock": 3},
{"name": "B", "price": -1, "stock": 0}, # 無効価格/在庫なし
{"name": "C", "price": 200, "stock": 5},
]
total = 0
for it in items:
if it["stock"] <= 0:
continue # 在庫なしはスキップ
if it["price"] <= 0:
continue # 無効価格もスキップ
total += it["price"] * it["stock"]
print(f"{it['name']} を計上")
print("総額:", total)
A を計上
C を計上
総額: 1420
バリデーションは先に、メイン処理は最後にが原則です。
while+breakの定番(入力ループ終了)
継続条件が入力依存のときはwhile True
とbreak
で「出口」を作るのがわかりやすいです。
# 空行が入力されたら終わるメモ取り
notes = []
while True:
s = input("メモ(空行で終了): ")
if s == "": # 終了条件を先に判定
print("終了します")
break
notes.append(s)
print("保存:", s)
print("メモ一覧:", notes)
メモ(空行で終了): 牛乳を買う
保存: 牛乳を買う
メモ(空行で終了): メール返信
保存: メール返信
メモ(空行で終了):
終了します
メモ一覧: ['牛乳を買う', 'メール返信']
終了条件を常に最初にチェックすることで、不要な処理を避けられます。
while+continueの定番(再入力を促す)
無効な入力が来たらエラーにせず、その周回だけcontinue
して再入力を促すのが親切です。
# 正の整数だけ受け付ける入力。無効なら再入力を促す。
nums = []
while True:
s = input("正の整数を入力(ENDで終了): ")
if s.upper() == "END":
break
if not s.isdigit() or int(s) <= 0:
print("無効な入力です。もう一度。")
continue # この周回はスキップし、次の入力へ
nums.append(int(s))
print("追加しました。現在:", nums)
print("最終データ:", nums)
正の整数を入力(ENDで終了): -3
無効な入力です。もう一度。
正の整数を入力(ENDで終了): 10
追加しました。現在: [10]
正の整数を入力(ENDで終了): abc
無効な入力です。もう一度。
正の整数を入力(ENDで終了): END
最終データ: [10]
エラーではなく「やり直し」へ導くのがユーザーフレンドリーです。
まとめ
break は「ループを止める」、continue は「この1回を飛ばす」—影響範囲の違いを理解すれば、エラー回避と効率化の両方を達成できます。
初心者は、終了条件や不正データのガードを先に判定し、合わない場合は早期break
/continue
する方針を徹底すると読みやすいコードになります。
特に、入力ループではwhile True
に出口としてのbreak
、バリデーションではcontinue
で早期スキップするのが効果的です。
「抜けるべき時はすぐ抜ける」「不要ならすぐ飛ばす」を合言葉に、堅牢で簡潔なループを書いていきましょう。