連載
» 2019年05月10日 05時00分 公開

Python入門:[Python入門]for文による繰り返し処理 (3/3)

[かわさきしんじ,Deep Insider編集部]
前のページへ 1|2|3       

break文とcontinue文による繰り返し処理の中断と継続

 繰り返し処理をしていると、その途中で繰り返しを終わらせたり、繰り返し処理を一度スキップしたりしたくなることがある。例えば、先ほどは次のようなコードを紹介した。

names = ['一色', 'かわさき', '遠藤']

for name in names:
    print(name)

リストの要素を全て表示するコード

 このコードは、リスト(人名録)に保存されたデータを全件画面に表示するものだ。だが、「リストから誰かの名前を探し出して、見つかったら何かの処理をしたい」場合を考えてみよう。これには、前回に紹介したif文を使える。例えば、「かわさき」が見つかったら「発見」と画面に表示して繰り返し処理を終了して、見つからなかったら「見つかりませんでした」と画面に表示することにしよう。上のコードを基に少し改変したのが次のコードだ(実際には、for文を使わなくとも同じ処理は可能だが、ここではサンプルということでご容赦願いたい)。

names = ['一色', 'かわさき', '遠藤']
target = 'かわさき'

for name in names:
    if target in name:
        print(f'発見: {name}')
else:
    print('見つかりませんでした')

人名を検索するコード(バージョン1)

 for文のブロックでは、if文を使って「変数targetに指定した名前がリストnamesの要素に含まれているかどうか」を調べている。if文の条件には第6回の「in演算子」で紹介した「in」演算子を使って、ループ変数nameに変数targetの値(ここでは文字列'かわさき')が含まれているかを指定している。これはリストの要素が'かわさきしんじ'などであっても、発見できるようにしたいからだ(条件の指定には、この他にも「==」演算子を使う、文字列のfindメソッドを使うなどの方法が考えられる)。

 リストnamesの要素から変数targetの値を含んだものが見つかれば、「発見: かわさき」などと表示される。見つからないまま、リストnamesの要素がなくなればelse節が実行されて、「見つかりませんでした」と表示される。実行結果を以下に示す。

人名は見つかったが、最後に「見つかりませんでした」とも表示される 人名は見つかったが、最後に「見つかりませんでした」とも表示される

 人名('かわさき')は見つかったが、最後に「見つかりませんでした」とも表示される。これでは見つかったのか、見つからなかったのかが分からない。なぜ、このような動作になったかというと、人名が発見されたときに、「繰り返し処理を終了」させるコードが書かれていないからだ。ループを途中で終わらせるには「break文」を使用する。

break文

 break文は、それを囲んでいる最も内側のループ(for文や次回取り上げるwhile文)を終了させる。このとき、for文やwhile文にelse節があってもそれは実行されない。よって、上のif文のブロック内でbreak文を実行することで、それを囲んでいるfor文の繰り返し処理が終了して、else節の実行もスキップされるようになる。

names = ['一色', 'かわさき', '遠藤']
target = 'かわさき'

for name in names:
    if target in name:
        print(f'発見: {name}')
        break
else:
    print('見つかりませんでした')

人名を検索するコード(バージョン2)

 実行すると、次のようになる。

探している人が見つかった 探している人が見つかった

 「for文のelse節」では以下の2つのコードはほぼ同じだと述べた。

for ループ変数 in 反復可能オブジェクト:
    ブロック

反復処理終了時に実行するブロック

else節のないfor文

for ループ変数 in 反復可能オブジェクト:
    ブロック
else:
    反復処理終了時に実行するブロック

else節のあるfor文

 だが、既に述べた通り、break文はelse節の実行をスキップする。そのため、常に両者のコードがほぼ同じ動作になるわけではないことに注意しよう。

continue文

 break文は「何らかの条件が成立したら、繰り返し処理の途中でそれを終了させる」ためのものだが、「何らかの条件が成立したら、繰り返し処理の途中で処理をスキップして、次の繰り返しに進みたい」こともある。これに使うのがcontinue文だ(これもfor文と次回取り上げるwhile文の両者で使用可能)。

 例えば、上のコードを少し変えてみよう。変更点は人名が1つ増えたことと、if文で条件が成立しなかったときに「繰り返し処理を継続します」と表示するようにしたところだ。

names = ['一色', 'かわさき', 'かわさきしんじ', '遠藤']
target = 'かわさき'

for name in names:
    if target in name:
        print(f'発見: {name}')
        break
    print('繰り返し処理を継続します')
else:
    print('見つかりませんでした')

人名を検索するコード(バージョン3)

 これを実行すると、次のようになる。

1人目の「かわさき」さんは見つかるが、もう1人は見つからない 1人目の「かわさき」さんは見つかるが、もう1人は見つからない

 これを実行すると、1つ目の'かわさき'が見つかった時点でbreak文によりfor文の繰り返し処理が終了するので、2つ目の'かわさきしんじ'が見つからない。これで十分な場合もあるが、そうではなく'かわさき'を含んだ要素を全て検索したいときには、「break文でループを終了させる」のではなく「ループを継続させる」必要がある。このようなときにcontinue文を使用する。

 ただし、ループ内での処理を全て行った上で、次の繰り返しに移るので問題なければ、continue文は必要ない。ここでは「繰り返し処理を継続します」と画面に表示するのをスキップしたいものとして、continue文を使ってみよう。

 continue文は、それを囲んでいる最も内側のループで次の繰り返し処理を開始する。例えば、上のコードでbreak文をcontinue文に置き換えてみよう。

names = ['一色', 'かわさき', 'かわさきしんじ', '遠藤']
target = 'かわさき'

for name in names:
    if target in name:
        print(f'発見: {name}')
        continue
    print('繰り返し処理を継続します')
else:
    print('見つかりませんでした')

人名を検索するコード(バージョン4)

 そうすると、リストの要素に変数targetの値(文字列'かわさき')が含まれていたときには、後続の処理(「繰り返し処理を継続します」を表示するprint関数呼び出し)がスキップされて、for文の先頭へ処理が移動して、次の繰り返しが行われる。実行結果を以下に示す。

今度は全ての「かわさき」さんが見つかったが…… 今度は全ての「かわさき」さんが見つかったが……

 すると、今度は文字列'かわさき'を含んだ全ての要素が見つかるが、最後に「見つかりませんでした」とも表示されるようになってしまった。なぜかというと、これまでのプログラムはbreak文の実行でelse節の実行がスキップされることに頼ったプログラムの書き方をしていたからだ(それが悪いわけではなく、プログラムに処理したい条件が変わったから、今までの書き方では都合が悪くなったということだ)。

 これを修正するには、名前が見つかったかどうかを覚えておく変数が必要になる。見つかったらTrueを、そうでなければFalseを保存しておき、最後にその値を基に「見つかりませんでした」と表示するかどうかを決めればよい。実際のコードは次のようになる。

names = ['一色', 'かわさき', 'かわさきしんじ', '遠藤']
target = 'かわさき'
found = False

for name in names:
    if target in name:
        found = True
        print(f'発見: {name}')
        continue
    print('繰り返し処理を継続します')

if not found:
    print('見つかりませんでした')

人名を検索するコード(バージョン5)

 変数foundが「見つかったかどうか」を覚えておくためのものだ。初期値をFalseとしてある。if文での人名検索の結果、リストの要素が変数targetの値を含んでいれば、その時点で「見つかった」ことを記憶するために、変数foundの値をTrueにしておく。

 最後に「見つかりませんでした」と表示するかどうかを決める部分は、else節に含めても、上のコードのようにelse節から外してfor文と同じインデント位置に書いても構わない(この場合、両者は同等の動作になる)。そこでは、前回に示したブール演算子の一つであるnot演算子を使用して、変数foundの値がFalseの場合(見つからなかった場合)にだけprint関数で「見つかりませんでした」と表示するようになっている。

 ここで行っている「繰り返しの中で何らかの状況やフラグの変化を保存しておいて、繰り返し処理が終わった後でそれらを基に処理を分岐させる」というのはよくあることだ。

 このコードを実行すると、次のように最後に「見つかりませんでした」と表示されなくなる。

見つかったときに「見つかりませんでした」と表示されなくなった 見つかったときに「見つかりませんでした」と表示されなくなった

 なお、ここで紹介したbreak文とcontinue文も「プログラムの実行の流れ」(フロー)を変更することから「制御構文」に分類されるものだ。

まとめ

 今回はPythonで繰り返し処理を行うために使われる構文であるfor文とbreak文、continue文を紹介した。次回は繰り返し処理で使われるもう一つの構文である「while文」について見ていくことにしよう。

今回のまとめ:for文、break文、continue文

  • for文はリストの要素に対して反復処理を行ったり、決まった回数の繰り返し処理を行ったりするために使う
  • 「for ループ変数 in 反復可能オブジェクト:」の次の行に繰り返し行う処理を記述する
  • 繰り返し行う処理はインデントを付けて、全ての文が同じインデント幅になるように記述する必要がある
  • for文で決まった回数の繰り返し処理を行うにはrange関数が使える
  • 繰り返し処理の中で、「何らかの条件が成立したら、それを中断する」にはbreak文を使用する
  • 繰り返し処理の中で、「何らかの条件が成立したら、以降の処理をスキップして、次の繰り返しに進む」にはcontinue文を使用する

「Python入門」のインデックス

Python入門

前のページへ 1|2|3       

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。