Python 入門

Python 制御フロー:break と continue 文

break 文と continue 文は、Python においてループ(Loop)の実行フローを制御するための非常に強力なツールです。

これらを使用することで、特定の条件に基づいてループの通常の実行順序を変更でき、コードに大きな柔軟性と効率性をもたらすことができます。本章では、これら2つの制御フロー文(Control Flow Statements)の使い方について詳細に解説します。

1. break 文

break 文は、ループ全体を途中で強制終了させるために使用されます。プログラムがループの内部で break 文に遭遇すると、ループの実行は即座に停止し、プログラムの制御権はループの直後に続く次のステートメントへとジャンプします。

1.1 基本的な使い方

break の最も一般的なユースケースは、ループの中で目的のターゲットが見つかった場合、あるいは特定の条件が満たされ、それ以上反復(Iteration)を続ける必要がなくなった場合です。

# 例文:リストの中から特定の数字を検索する
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
target = 5

for number in numbers:
    print(f"数字をチェック中: {number}")
    if number == target:
        print(f"ターゲットを発見: {target}")
        break  # ターゲットが見つかったらループを抜ける
    else:
        print(f"{number} はターゲットではありません。")

print("ループが終了しました。")

この例では、ループが numbers リストを走査します。numbertarget(つまり 5)と等しくなったとき、break 文が実行され、ループが直ちに終了します。出力結果は以下の通りです:

数字をチェック中: 1
1 はターゲットではありません。
数字をチェック中: 2
2 はターゲットではありません。
数字をチェック中: 3
3 はターゲットではありません。
数字をチェック中: 4
4 はターゲットではありません。
数字をチェック中: 5
ターゲットを発見: 5
ループが終了しました。

1.2 ネストされたループにおける break

ネスト(入れ子)されたループ(ループの中にもう一つのループがある構造)の中で break 文を使用すると、それはその break 文を含んでいる最も内側のループのみを終了させます。

# 例文:内側のループを抜ける
for i in range(3):
    print(f"外側のループ反復: {i}")
    for j in range(5):
        print(f"  内側のループ反復: {j}")
        if j == 2:
            print("  内側のループを抜けます")
            break  # ここでは内側の for ループのみを抜ける
    print("外側のループの実行を継続します")

print("プログラムが終了しました。")

実行結果:

外側のループ反復: 0
  内側のループ反復: 0
  内側のループ反復: 1
  内側のループ反復: 2
  内側のループを抜けます
外側のループの実行を継続します
外側のループ反復: 1
  内側のループ反復: 0
  内側のループ反復: 1
  内側のループ反復: 2
  内側のループを抜けます
外側のループの実行を継続します
外側のループ反復: 2
  内側のループ反復: 0
  内側のループ反復: 1
  内側のループ反復: 2
  内側のループを抜けます
外側のループの実行を継続します
プログラムが終了しました。

ご覧の通り、j が 2 になるたびに内側のループは終了しますが、外側のループは次の反復(イテレーション)を継続します。

1.3 while ループにおける break

while ループにおける break 文の挙動は、for ループの場合と全く同じです。

# 例文:while ループの中断
count = 0
while True:  # 無限ループ
    print(f"現在のカウント: {count}")
    count += 1
    if count > 5:
        print("while ループを抜けます")
        break  # count が 5 を超えたらループを終了
        
print("ループが終了しました。")

出力結果:

現在のカウント: 0
現在のカウント: 1
現在のカウント: 2
現在のカウント: 3
現在のカウント: 4
現在のカウント: 5
while ループを抜けます
ループが終了しました。

このケースでは、while True によって無限ループ(Infinite Loop)が作成されていますが、break 文によって count が 5 を超えた時にループが強制終了されることが保証されています。

2. continue 文

continue 文の役割は、現在の反復(イテレーション)の残りのコードをスキップし、ループの次の反復へと直接進むことです。break とは異なり、ループ全体を終了させるわけではなく、あくまで「今回分」の処理を飛ばすだけです。

2.1 基本的な使い方

特定の条件に基づいてループ内の一部の操作をスキップしたいが、ループ自体の走査は最後まで続けたい場合に continue 文は非常に有用です。

# 例文:リストの中の奇数のみをプリントする
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

for number in numbers:
    if number % 2 == 0:  # 偶数かどうかをチェック
        continue  # 偶数の場合、今回の反復の残りの処理(print)をスキップ
    print(f"奇数: {number}")

print("ループが終了しました。")

出力結果:

奇数: 1
奇数: 3
奇数: 5
奇数: 7
奇数: 9
ループが終了しました。

この例では、number が偶数の時に continue 文が実行され、その回の print 文がスキップされます。その結果、奇数のみが出力されます。

2.2 ネストされたループにおける continue

break と同様に、ネストされたループで continue を使用した場合、その continue 文を含んでいる最も内側のループにのみ影響を与えます。

# 例文:ネストされたループでの continue の使用
for i in range(3):
    print(f"外側のループ反復: {i}")
    for j in range(5):
        if j == 2:
            print("  内側ループの第 2 回目の反復をスキップします")
            continue  # 内側ループの現在の反復をスキップ
        print(f"  内側のループ反復: {j}")
    print("外側のループの実行を継続します")

print("プログラムが終了しました。")

出力結果:

外側のループ反復: 0
  内側のループ反復: 0
  内側のループ反復: 1
  内側ループの第 2 回目の反復をスキップします
  内側のループ反復: 3
  内側のループ反復: 4
外側のループの実行を継続します
...(以下同様に継続)

j が 2 のとき、continue 文によって内側ループの残りの print はスキップされますが、内側ループはすぐに次の j の値を使って実行を続けます。

2.3 while ループにおける continue

while ループで continue を使用する際は、無限ループに陥らないよう細心の注意が必要です。continue をトリガーする条件が、ループ変数の更新(アップデート)を妨げないようにしなければなりません。

# 例文:while ループでの continue の使用
count = 0
while count < 10:
    count += 1  # 重要:条件チェックの前にカウンタを更新する
    if count % 2 == 0:
        print(f"偶数をスキップ: {count}")
        continue  # 偶数の場合スキップ
    print(f"奇数: {count}")

print("ループが終了しました。")

出力結果:

奇数: 1
偶数をスキップ: 2
奇数: 3
...
偶数をスキップ: 10
ループが終了しました。

この例では、インクリメント操作(count += 1)が continue 文よりも前に配置されています。これにより、continue が実行されても変数は更新され続け、ループは正常に終了します。もし count += 1 をループの最後(if ブロックの後)に置いてしまうと、最初の偶数に遭遇した時点で continue によってループの先頭に戻り続け、count が一生増えない無限ループに陥ってしまいます。

3. 実践的な活用ケース

3.1 ケース 1:ユーザー入力のバリデーション

ユーザーに一連の数字を入力させ、有効な数値のみを処理し、無効な入力はスキップして再入力を促すプログラムを想定します。

# 例文:ユーザー入力のバリデーション
while True:
    user_input = input("数字を入力してください('q' で終了): ")
    
    if user_input.lower() == 'q':
        break  # 'q' が入力されたらループを終了
        
    try:
        number = float(user_input)  # 浮動小数点数への変換を試みる
        print(f"入力された数字: {number}")
    except ValueError:
        print("無効な入力です。有効な数値を入力してください。")
        continue  # 数値でない場合、スキップして次の入力を待つ

このケースでは:

  • while True は、ユーザーが 'q' を入力して break するまで走り続けます。
  • try-except ブロックで型変換(Casting)を試みます。
  • 変換に失敗した場合(ValueError)、continue によって後続の処理を飛ばし、再び入力を促します。

3.2 ケース 2:データのフィルタリング

リスト内の多様なデータから、特定の基準を満たす要素のみを抽出・処理します。

# 例文:データのフィルタリング(Filtering)
data = [10, -5, 20, -2, 0, 15, -8, 5]

for value in data:
    if value <= 0:
        continue  # 正の数でない場合はスキップ
    print(f"正の数を処理中: {value}")

このケースでは:

  • value が 0 以下の時、continue 文によってプリント処理が飛ばされます。
  • 結果として、正の数(Positive Numbers)のみが処理対象となります。

3.3 ケース 3:最初の素数を探す

指定された範囲内で最初に出現する素数(質数)を見つけます。

# 例文:最初の素数を検索
def is_prime(n):
    """数値が素数かどうかを判定する"""
    if n <= 1:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

for number in range(2, 20):  # 2 から 19 までの数字をチェック
    if is_prime(number):
        print(f"最初に見つかった素数: {number}")
        break  # 最初の素数を見つけたら即座にループを終了

このケースでは:

  • is_prime 関数で判定を行い、素数が見つかった瞬間に break を使用してループを終了させます。これにより、無駄な計算(残りの数値のチェック)を省くことができます。