Python | Break を使わない場合のコード(比較用)

Python
スポンサーリンク

「見つかったら止める」をやりたいのに break を使わないとどう書くか。初心者でも読める形で、代表的な書き方と例題を並べて説明します。


全体の考え方

  • 目的: 条件が満たされたら、それ以上の処理を回さないこと。
  • 基本戦略: ループ条件に「見つかったかどうか」を組み込む、または関数ごと終了する。
  • 選び方: 小さなスクリプトならフラグで十分、再利用したいなら関数の return が最も読みやすい。

パターン1: フラグ変数+while 条件で止める

ループを「見つかっていない間だけ」回すように設計します。外側・内側の両方を自然に止められます。

# 例題: リストから最初の3の倍数を探す(break なし)
numbers = [5, 7, 10, 12, 20]

found = False
i = 0
value = None

while i < len(numbers) and not found:
    if numbers[i] % 3 == 0:
        value = numbers[i]
        found = True
    i += 1

print(value if found else "3の倍数は見つかりませんでした")
Python
  • ポイント: while の条件に not found を入れると、「見つかったら回さない」が明快。
  • メリット: 入れ子ループでも、両方の while が止まる。
  • 注意: インデックス操作が必要なので、for よりコードが増える。

パターン2: フラグ変数+for で最後に判定

for を使いつつ break は避けたい場合、ループ中は「見つけても覚えておく」だけにして、終了後に結果をまとめます。

# 例題: リストから最初の偶数を探す(break なし)
numbers = [3, 7, 11, 18, 21]

found = False
value = None

for n in numbers:
    if not found and n % 2 == 0:  # すでに見つけていたら何もしない
        value = n
        found = True

print(value if found else "偶数は見つかりませんでした")
Python
  • ポイント: 1回目だけ拾い、それ以降はスルーする条件にする。
  • メリット: for の読みやすさを保ったまま、break を使わずに早期検出。
  • 注意: ネストしたループでは外側まで止められない。フラグを外側の条件に使うか、関数化へ。

パターン3: 関数化して return で早期終了

「見つかったら処理全体をやめたい」なら、関数化して return を使うのが最もシンプルで読みやすい方法です。

# 例題: リストから最初の負の数を返す(break なし)
def find_first_negative(numbers):
    for n in numbers:
        if n < 0:
            return n      # 見つかったら関数ごと終了
    return None            # 見つからなかった場合

result = find_first_negative([5, 3, -2, 7, -8])
print(result if result is not None else "負の数は見つかりませんでした")
Python
  • ポイント: 「結論が出たら関数を終わる」意図が明確。
  • メリット: 再利用・テストがしやすい。入れ子ループでも関数単位で止められる。
  • 注意: スクリプト直書きだと return は使えないので、関数に切り出す。

パターン4: ジェネレータ式+next で最初だけ取得

「最初に一致したものだけ欲しい」ケースに強い、Python らしい書き方です。短くて意図が伝わります。

# 例題: リストから最初のゼロを探す(break なし)
numbers = [5, 3, 0, 7, 0]

first_zero = next((n for n in numbers if n == 0), None)
print(first_zero if first_zero is not None else "ゼロは見つかりませんでした")
Python
  • ポイント: next(generator, default) は「最初の一致」だけ取り出す定番。
  • メリット: 自動で早期打ち切りされ、コードが非常に短い。
  • 注意: ジェネレータ式に慣れていないと読みにくく感じることがある。

パターン5: 入れ子ループを while+フラグで止める

二重ループ以上では、break なしで外側まで止めるには「ループ条件にフラグ」を入れるのが分かりやすいです。

# 例題: 2次元リストから最初の文字列を探す(break なしで外側も止める)
grid = [
    [10, 3.14, True],
    ["hello", 42, None],
    ["world", 0, False],
]

found = False
value = None
i = 0

while i < len(grid) and not found:
    j = 0
    while j < len(grid[i]) and not found:
        x = grid[i][j]
        if isinstance(x, str):
            value = x
            found = True
        j += 1
    i += 1

print(value if found else "文字列は見つかりませんでした")
Python
  • ポイント: どのループも「見つかっていない間だけ回す」ようにする。
  • メリット: break なしで、処理全体の早期終了を実現。
  • 注意: インデックスと状態の管理が増えるため、丁寧に書く。

どれを選ぶかの指針

  • 小さなスクリプトなら: フラグ+while か、フラグ+for(終了後に判定)が手軽。
  • 再利用したいなら: 関数+return が第一候補。入れ子でも自然に止められる。
  • 短く書きたいなら: ジェネレータ+next。最初の一致を取る意図が明快。
  • ネストが深いなら: while の条件にフラグを入れるか、関数に切り出して return。

よくある落とし穴と対策

  • インデックス更新忘れ:
    • 対策: while の末尾で必ず i や j を進める。進め忘れは無限ループの原因。
  • フラグの初期化漏れ:
    • 対策: found は必ず False で開始。見つかった値を保持する変数も初期化しておく。
  • 読みづらい条件合成:
    • 対策: while 条件が複雑なら、意味のある名前のフラグに分解する(例: not_found, in_range)。

練習問題(自分の手で動かして確認)

  • 偶数の最初の値: フラグ+for と 関数+return の両方で実装して比較。
  • None の検出: ジェネレータ+next で最初の None を取り、見つからない場合は “なし” を表示。
  • 二重ループ: 2次元リストから最初の負の数を探し、while+フラグで外側まで止める。

「なぜ止めたいのか」を言葉にしてみると、break を使わずに止める設計が自然に選べるようになります。

Python
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました