トップページ -> Python入門 基礎編 -> break continue文を扱おう

break continue文を扱おう!

前回はfor文による繰り返し処理の基本について学びました. 今回は繰り返し処理を途中で止めるbreak文と,処理をスキップするcontinue文について解説します.

break文

break文を使うことでfor文の繰り返し処理を途中で止めることができます. 繰り返し処理の中にbreakと書くことでbreakに到達したらその繰り返し処理を打ち切ります.
例えば次のような問題を考えてみましょう.

例題

入力された整数が素数であるかどうかを判定するプログラムを書きましょう.

例題の解答例


import time

n = int(input())
start_time = time.time()
is_prime = True # 素数であると仮定しておく

# 素数かどうか判定する部分
for i in range(2,n):
    if n%i == 0: # 割り切れるかの判定
        is_prime = False # 割り切れた場合は素数でない
        
elapsed_time = time.time() - start_time
print("経過時間:",elapsed_time)
print(is_prime)
timeと書いてある部分は処理時間を計測するためのコードですので今は気にしないでください.
2からn-1までのすべての数でnを割ってみて割り切れたら素数でないと判定するプログラムです.
小さい数なら素早く判定してくれますね.
試しに 100000000 を入力してみましょう.すると…
素朴な素数判定
結構時間がかかりますね.表示される経過時間はお手元の環境次第で変わります. 素数かどうか分かりにくい数ならともかく明らかに偶数な 100000000 にこれだけ時間がかかっているようでは困ります.
もう一度プログラムを見てみましょう. 実は素数かどうか判定する繰り返し処理の1回目で割り切れてしまうため is_prime はすぐにFalseになります.
これ以降の計算はすべて無駄な処理です. is_prime が False になった瞬間に処理を打ち切り結果を出力させればよいのです. break文を使って無駄な処理を省いてみます.

import time

n = int(input())
start_time = time.time()
is_prime = True # 素数であると仮定しておく

# 素数かどうか判定する部分
for i in range(2,n):
    if n%i == 0: # 割り切れるかの判定
        is_prime = False # 割り切れた場合は素数でない
        break # 割り切れてしまったらそこで打ち切り
        
elapsed_time = time.time() - start_time
print("経過時間:",elapsed_time)
print(is_prime)
素朴な素数判定2
breakに到達した瞬間に繰り返し処理は終了します. ある条件を満たしたら繰り返し処理を打ち切りたい場合などに便利です.

continue文

continue文を用いることでcontinue以降の処理をスキップすることができます. 実際のプログラムを見てみましょう.


for i in range(30):
    if i%2 == 0:
        continue # continueに到達するとそれ以降の処理は行わない
        
    print(str(i) + "は奇数")
continue文
あまりいい例ではありませんが,continueに到達すると,それ以降の print(str(i) + "は奇数") は行われていません. 知識として知っている必要はありますが,continueを使わずに記述する場合が多いためbreakほどは見ないかもしれません.

余談 ~エラトステネスの篩~

本当に余分な話です.素数の判定に興味がない人はスキップしていただいて構いません. この部分を読んだからといって今後の解説が理解しやすくなるようなことは一切ありません.
先ほど素数の判定を行ったのですが,せっかくなので入力nまでの素数のリストが欲しい と思った人はいませんか? 先ほど作った素数判定プログラムを利用することで簡単に作れます.


# 素朴な素数判定
import time

n = int(input())
prime_list = []
start_time = time.time()

for num in range(2,n+1): # 2からnまでのすべての数に対して実行
    # 素数かどうかを判定する部分
    is_prime = True # 素数であると仮定しておく
    for i in range(2,num):
        if num%i == 0: # 割り切れるかの判定
            is_prime = False # 割り切れた場合は素数でない
            
    # 素数だったら素数のリストに追加する
    if is_prime:
        prime_list.append(num)

elapsed_time = time.time() - start_time
print("経過時間:",elapsed_time)
print(prime_list)
100を入力して挙動を確かめましょう.
素数のリスト1
あっていそうですね. では,10000を入力してみましょう.
素数のリスト2
10000までの素数判定はコンピュータでもそこそこ大変みたいですね. それもそのはず.素数のリストを得るということに関してはこのプログラムは無駄が多いんです.
より高速な判定方法を考えてみましょう. 1からnまでの数のリストから素数2,3,5,… の倍数を順番にふるい落としていけば,簡単に判定できそうです. それほど手間がかからずに書けるので少し考えてみてください. ちなみに,len(my_list) と書くことで my_list の長さを取得できます.
以下,ヒントです. 手順1は num_list = [True for i in range(n+1)]と書くことで実現できます.
  1. 長さn+1のすべての要素がTrueとなるリストを作る
  2. iが素数であれば,True 素数でなければFalseとなるようにすることを考える
  3. 0,1は素数でないのでFalseとしておく
  4. 繰り返し処理を行いリストを更新していく
以下,解答例です.

import time
n = int(input())

num_list = [True for i in range(n+1)] # 長さn+1のリストを作る
prime_list = [] # 素数を追加するための空のリスト
num_list[0] = False # 0は素数でない
num_list[1] = False # 1も素数でない
start_time = time.time()

# 素数かどうかを判定する部分
for num in range(len(num_list)):
    if num_list[num]:
        for i in range(num*2,n+1,num): 
            num_list[i] = False # num*2 から n+1 までの numの倍数をFalseとする
            
elapsed_time = time.time() - start_time
print("経過時間:",elapsed_time)

# 素数のリストを作る部分
for i in range(n+1):
    if num_list[i]: # もし素数であれば
        prime_list.append(i) # 素数のリストに追加する
        
print(prime_list)
あまり大きな数字を入力すると "IOPub data rate exceeded." と表示されエラーになるので気を付けてください. nが大きくなるとprime_listも膨大になるため,出力の処理が強制停止されます.
どのくらい速くなったか確かめてみるために10000を入力します
エラトステネスの篩1
段違いに速くなりましたね.
次は 10000000 を入力してみましょう.print関数を付けたままだと強制停止するのであらかじめコメントアウトしておきます.
エラトステネスの篩2
どうやら10秒かからずに 10000000 までのすべての数の素数判定が終わるようです.
素数かどうかを判定する部分の
for num in range(len(num_list)) を
for num in range(int(len(num_list))**2 + 1) に
for i in range(num*2,n+1,num) を
for i in range(num*num,n+1,num) に変えることで無駄を省くこともできます.
判定に使う素数p未満の倍数は既に取り除かれており,取り除くべき数はp**2以上であるためです.

# 一番早いやつ
import time
n = int(input())

num_list = [True for i in range(n+1)]
prime_list = []
num_list[0] = False
num_list[1] = False
num_list[2] = True
start_time = time.time()

for num in range(int(len(num_list)**0.5)+1):
    if num_list[num]:
        for i in range(num*num,n+1,num):
            num_list[i] = False
            
elapsed_time = time.time() - start_time
print("経過時間:",elapsed_time)

for i in range(n+1):
    if num_list[i]:
        prime_list.append(i)
        
print(prime_list)
10000000を入力して処理時間を比べてみましょう.
エラトステネスの篩3
結構露骨に変わりますね. ここで紹介したプログラムはエラトステネスの篩という素数判定の有名なアルゴリズムです. 素朴な素数判定と比べると圧倒的に速いことがわかってもらえたと思います. 同じ結果が得られるプログラムでも書き方次第で劇的に速さが変わるのです. より詳しくは Pythonで数学をしてみよう! の素数判定のページで解説をしています. 余談の方が長くなった気がしますがきっと気のせいです.

今回はbreak文とcontinue文について解説しました. break文による処理の打ち切りは頻繁に利用するためしっかりマスターしましょう. 次回はwhile文による繰り返し処理について解説します.

<- 前へ戻る 【目次に戻る】 次へ進む ->