Pythonのfor文で途中で抜ける方法【break文】
目次
Pythonのfor文で途中で抜けるには?
Pythonのfor文を使っているとfor文の途中でループから抜け出したい時があります。
そういうときはPythonではどうするのかと言うとbreak文を使うのが一般的です。
この記事ではPythonのfor文から途中で抜ける方法について具体的に解説します。
基礎となるbreak文の他、トリッキーなraiseを使った方法も解説します。
(^ _ ^) | ループからの脱出 |
break文でfor文から抜ける
Pythonのbreak文はループ文の中で使える文です。
これを使うとbreakを実行した直後にループから1つ抜けることが可能です。
具体的な使い方は以下になります。
for i in range(10): print(i) break
上記のfor文を見てみます。
for i in range(10):
となってます。
これはループを10回回し、カウント変数はi
でカウントするという意味です。
range(10)
というのは数列を生成するコードで、ここで生成されていく数列がi
に保存されていきます。
for文の中では
print(i) break
と書いています。
これはカウント変数i
をprint()
文で出力するという意味です。
その出力の直後にbreak
でループから抜けています。
ループから抜けると当然、ループはそこでストップします。
ですのでカウント変数は0
でストップするわけですね。
よって上記のコードの出力結果は
0
になります。
if文とbreak文を組み合わせる
では次のようなコードはどうでしょうか。
for i in range(10): print(i) if i == 4: break
実はbreak
文はループの中で他の文と組み合わせて使うことができます。
上記の例ではif
文と組み合わせています。
if i == 4:
となっていますが、これはカウント変数i
が4
になったら真になる条件文になっています。
真になるとif
文の中身であるbreak
文が実行されます。
よってこの上記のコードを実行すると
0 1 2 3 4
という出力結果になります。
カウント変数i
が4
になったらループから脱出していますね。
このようにbreak
文はif
文などと組み合わせると複雑な条件でループから脱出できます。
入れ子になったfor文
break
文は直近のfor
文に対して実行されます。
これはどういうことでしょうか。
このbreak
文の振る舞いを見るには入れ子になったfor
文を見るのが手っ取り早いです。
下のコードを見てください。
for i in range(4): print('i', i) for k in range(4): print('k', k) break
入れ子になったfor文の振る舞いは大丈夫でしょうか?
上のコードは以下のコードに書き換えることができます。
for i in range(4): print('i', i) for k in range(4): print('k', k)
上記のコードはbreak
文が入っていません。
ですので出力結果は以下になります。
i 0 k 0 k 1 k 2 k 3 i 1 k 0 k 1 k 2 k 3 i 2 k 0 k 1 k 2 k 3 i 3 k 0 k 1 k 2 k 3
入れ子になったfor
文ではまず最初に外側のfor
文が実行されます。
つまり
for i in range(4): print('i', i) for k in range(4): print('k', k)
であれば最初にfor i in range(4):
のループが回ります。
子のループが回るとprint('i', i)
が実行され、そのあとに2つ目のfor
文に入っていきます。
2つ目(中側)のfor
文ではfor k in range(4):
となっていますので、ループが4回回ります。カウント変数はk
です。
つまり外側のfor
文でprint()
が実行されると、中側のfor
文が4回回ることになります。
それが外側のfor
文のカウントが終わるまで、つまり4回まで続きます。
外側が4回、中川が4回なのであわせて4 * 4
で16回のループが回ります。
これが入れ子になったfor
文の動作です。
ではもう一度、最初のコードに戻ります。
for i in range(4): print('i', i) for k in range(4): print('k', k) break
上記のコードには中側のfor
文の中にbreak
文が入っています。
よって上記のコードを実行すると
i 0 k 0 i 1 k 0 i 2 k 0 i 3 k 0
という結果になります。
中側に書かれているbreak
文は中側のfor
文に対してのみ作用します。
つまり作用というのは中側のループから抜けるということです。外側のループからは抜けません。
外側のループは4回回りますので、中側のループから抜けても外側で4回ループすることになります。
よってカウント変数は上記のように出力されます。
このようにbreak
文はbreak
文が書かれているfor
文に対してのみ作用します。
ネストされたfor文から一挙に脱出するには?
ネストされたfor
文で内側のfor
文内の条件によって外側のループからも抜けたいケースがあります。
こういう時はフラグを使うのが一般的です。
loop = True for i in range(4): for k in range(4): loop = False break if not loop: break print('done')
このコードではloop
というフラグ変数を使っています。フラグとは真偽値であらわされた変数のことです。
中側のループでloop = False
とやってTrue
だったloop
のフラグを折っています。折るとはFalse
にすることです。
その直後、中側のループからbreak
し、if not loop:
に行きます。
そうするとloop
はFalse
になっているのでこの条件式はTrue
になり、if
文の中のbreak
が実行されます。
そうして外側のループから脱出し、めでたく入れ子のループから抜け出すことができます。
ちなみにC言語などはgoto
文というのがあって入れ子になったループからも簡単に脱出できますが、Pythonにはないので代わりにraise
などを代用することがあります。
raise
を使って入れ子のループから脱出するコードは以下になります。
try: for i in range(4): for k in range(4): print('raise!') raise Exception except Exception: pass print('done')
このコードの出力結果は以下になります。
raise! done
raise
というのは例外を送出する文です。
例外というのはエラー処理に使われます。
たとえばファイルが無かったりとか、メモリが不足していたりとか、そう言う時に例外は使われます。
つまりraise
はネストされたfor
文から抜け出すための文ではなく、これはトリッキーな使い方になります。
raise
が実行されるとそこからジャンプが発生して、try
文のexcept
にいきます。
raise Exception
でException
例外を送出しているので、except
でキャッチするときもException
を指定します。
送出された例外はキャッチしないとスタックトレースになってプログラムの実行が中断されます。
このコードの問題点は、ループの中で本来の意味での例外が発生したときにまぎらわしいことです。
ループの中でException
例外が発生してもこのコードではなにも処理せずに通過させます。
なぜならネストされたループの脱出にException
を使っているからです。
この問題を解決するにはException
例外を継承して独自例外を作り、その独自例外でジャンプするという方法があります。
この独自例外はループから脱出する場合にのみ使用する例外になります。
class Break(Exception): pass
しかし、これは可能なことは可能ですが、やっている人いるんでしょうか。
私も見かけたことありません。
お作法的にはあまり良くないと思うので、フラグを使う方を採用された方がいいかもしれません。
おわりに
今回はPythoのfor
文から抜ける方法を解説しました。
break
文を使えばループから脱出可能です。
(^ _ ^) | 大脱走 |
(・ v ・) | さらばループよ |