基礎

Pythonのループと条件分岐:for、while、range、enumerate、break、if/elif、match/case

更新日: · Skillaria.Top

Pythonのループは処理を繰り返す仕組みです。forはリストや範囲(range())の要素を順に取り出し、whileは条件が成り立つ間繰り返します。breakでループを抜け、continueで今の回の残りを飛ばし、enumerate()で番号を付けられます。判断にはif/elif/elseを使い、データの形で分岐するならmatch/case(Python 3.10以降)を使います。

Pythonのループは、同じ処理を繰り返すために使います。買い物リストを1行ずつ処理する、ファイルの各行を読み込む、正しい数字が入力されるまで質問を続ける、といった場面です。Pythonのループには for と while の2種類があります。その中で判断するには if/elif/else の条件分岐や match/case を使います。ここでは、それぞれの道具を実際に使える例とともに見ていきます。

条件分岐:if、elif、else

if文は、条件式が真のときだけブロックを実行します。ブロックは4つのスペースのインデントで示します。Pythonには波かっこがないため、インデントが正しくないと、すぐに IndentationError が出ます。

spent = 4200
limit = 5000

if spent > limit:
    print("予算を超えました")
elif spent > limit * 0.8:
    print("予算の残りは20%未満です")
else:
    print("問題ありません")

elif の条件は上から順に調べられ、最初に当てはまったものだけが実行されます。そのため、厳しい条件は上に書きます。もし spent > limit * 0.8 を先頭に置くと、予算超過のメッセージは決して表示されません。

何が「真」とみなされるか

条件に比較式を書く必要はありません。偽とみなされるのは False、None、ゼロ(0、0.0)、空のコレクション(""、[]、{})です。それ以外はすべて真です。そのため「リストが空でないか」は短く書けます。

expenses = []
if not expenses:
    print("まだ支出はありません")

条件は and、or、not で組み合わせられます。範囲の判定は比較を連ねて書けます。例:if 0 < amount <= 100_000:。短い選択には三項演算子も使えます。例:status = "多め" if spent > limit else "通常"。

Pythonのforループ:構文と例

Pythonの for は、Cのようなカウンタではなく、要素を1つずつ取り出す仕組みです。リスト、文字列、辞書、ファイル、範囲など、繰り返し可能なオブジェクトの要素を先頭から順に受け取ります。他の言語でいうforeachにあたるのが、Pythonの通常の for です。

expenses = [350, 1200, 89, 4500]
total = 0
for amount in expenses:
    total += amount
print(total)  # 6139

構文は for 変数 in コレクション: で、その後にインデントされたブロックが続きます。ループが終わった後も、変数には最後の値が残ります。これが役立つこともありますが、大きなプログラムで頼るのはおすすめしません。

文字列、リスト、辞書のループ

文字列は1文字ずつ、リストは要素ごとに処理されます。辞書をそのままループすると、キーが順に取り出されます。キーと値を同時に取り出すには .items() を使います。

by_category = {"食費": 3200, "交通費": 900, "映画": 600}

for category, amount in by_category.items():
    print(f"{category}: {amount}円")

値だけを取り出すには .values() を使います。ループの途中で辞書のサイズを変えるとエラーになります。RuntimeError: dictionary changed size during iteration が出ます。要素を削除したい場合は、コピーを回しましょう。例:for key in list(d):。

range関数:数字で繰り返す

数字を順に回したいときは range() を使います。range() はメモリ上にリストを作らず、数字を1つずつ生成するので、range(10**9) でも一瞬で準備できます。

呼び出し生成される数字
range(5)0, 1, 2, 3, 4
range(2, 6)2, 3, 4, 5
range(0, 10, 3)0, 3, 6, 9
range(5, 0, -1)5, 4, 3, 2, 1

覚えておくべきルールは、終わりの値は範囲に含まれないことです。range(1, 10) は9で終わります。これは「1つずれる」エラーのよくある原因です。ステップは負にできますが、0にはできません。

for i in range(1, 4):
    print(f"{i}日目")
# 1日目
# 2日目
# 3日目

enumerate:ループの中で番号を付ける

要素の番号が必要なとき、初心者は for i in range(len(items)) と書きがちです。動きますが、読みにくくなります。enumerate() は「番号と要素」のペアを返します。start 引数で、数え始める番号を指定できます。

items = ["コーヒー", "タクシー", "昼食"]
for n, item in enumerate(items, start=1):
    print(n, item)
# 1 コーヒー
# 2 タクシー
# 3 昼食

2つのリストを並行して回すには zip() を使います。例:for name, price in zip(names, prices):。zip() は最も短いリストで止まります。Python 3.10以降では strict=True を渡すと、長さが違うときにエラーになります。

Pythonのwhileループ

while は、条件が真の間ブロックを繰り返します。繰り返し回数が事前に分からないときに使います。正しい入力を待つ、データを最後まで読む、成功するまで問い合わせを繰り返す、といった場合です。

balance = 10_000
month = 0
while balance > 0:
    balance -= 2_700
    month += 1
print(f"お金は{month}か月分あります")  # 4

大きな落とし穴は、条件に使っている変数を変えるのを忘れることです。そうするとループが終わりません。プログラムが止まってしまったら、Ctrl+C を押してください。Pythonは KeyboardInterrupt で実行を中断します。

無限ループとdo while

無限ループは、わざと書くこともあります。while True: を書き、break で抜けるパターンです。Pythonには do while 構文がありません。代わりに、このパターンが後判定のループの役割を果たします。ブロックは必ず1回は実行され、判定はブロックの最後に来ます。

while True:
    raw = input("金額: ")
    if raw.isdigit():
        amount = int(raw)
        break
    print("整数を入力してください")

for で無限ループを作るのは珍しく、itertools.count() のような無限のイテレータを回すときだけです。

breakとcontinue:ループを抜ける、回を飛ばす

break はループを直ちに終わらせ、ループの後のコードに進みます。continue は、今の回の残りを飛ばして次の回に進みます。

expenses = [350, -10, 1200, 0, 99_999, 89]

for amount in expenses:
    if amount <= 0:
        continue          # この回をスキップ
    if amount > 50_000:
        print("不審な金額のため停止します")
        break             # ループを抜ける
    print(amount)

表示されるのは 350 と 1200 で、その後に警告が出てループが終わります。89 には到達しません。どちらの文も、自分を含む一番内側のループに対してだけ働きます。

ループのelse

for と while には、少し珍しい else 節もあります。ループが break なしで最後まで回ったときに実行されます。検索処理に便利です。

for amount in expenses:
    if amount > 50_000:
        print("大きな支出を見つけました")
        break
else:
    print("大きな支出はありません")

多重ループ(ネストしたループ)

ループの中にループを入れると、内側のループは外側の1回ごとに最後まで実行されます。表や行列を回ったり、組み合わせを作ったりするときに使います。

for row in range(1, 4):
    for col in range(1, 4):
        print(row * col, end="\t")
    print()

注意点が2つあります。1つ目は、計算量が急に増えることです。10,000個の要素を持つ2重ループは、1億回の処理になります。2つ目は、break が抜けられるのは内側のループだけという点です。両方を止めたいなら、ループを関数に入れて return で抜けるのが、フラグを使うより分かりやすい方法です。

match/caseの使い方

Python 3.10以降では、if cmd == ... elif ... が長く続くときに match 文(PEP 634)が使えます。これは単なるswitchではありません。値を形のパターンと照合し、同時にその一部を変数に取り出せます。

def parse(text):
    match text.split():
        case ["add", item, amount]:
            return f"追加 {item}: {amount}"
        case ["list"] | ["ls"]:
            return "支出を表示"
        case ["quit"]:
            return "終了"
        case _:
            return "不明なコマンドです"

print(parse("add コーヒー 250"))  # 追加 コーヒー: 250
print(parse("add コーヒー"))      # 不明なコマンドです

パターン ["add", item, amount] に一致するのは、要素がちょうど3つで、先頭が "add" のリストだけです。金額のないコマンドは、すべてを受け止める _ の節に入ります。| は複数の候補をまとめます。

辞書のパターンとガード条件

辞書のパターンは、書いたキーだけを確認し、ほかのキーは無視します。int(a) は型を確認すると同時に値を取り出します。パターンの後に if を付けると、追加の条件(ガード)になります。

match event:
    case {"type": "expense", "amount": int(a)} if a > 10_000:
        print("大きな支出", a)
    case {"type": "expense", "amount": int(a)}:
        print("支出", a)

matchの一番の落とし穴

case の後に裸の名前を書くと、それは比較ではなく取り込み(キャプチャ)になります。case limit: はどんな値にも一致し、その値を limit に入れてしまいます。定数と比べたいときは、case Color.RED: のようにドット付きの名前を使うか、リテラルを書きます。

Python 3.10以降でmatchの構文はほとんど変わっていません。Python 3.15では、小さな非対称性が解消されました。以前は、リテラルのパターンで数字の前にマイナス記号を付けた形しか使えませんでした。今は case +1: も書けます。古いバージョンでは、このコードは構文エラーになります。

ループでよくあるミス

  • ループ中にリストを変更する。 for の中で要素を削除すると、隣の要素が飛ばされます。新しいリストを作るのが安全です。例:clean = [x for x in items if x > 0]。
  • rangeの終わり。 range(1, n) は n を含みません。
  • whileで条件の変数を変えない。 無限ループになります。
  • ループの中で += で文字列を連結する。 量が多いと、"".join(parts) より遅くなります。
  • 比較の代わりに代入する。 if x = 5 は構文エラーです。比較には == を使います。

ループの練習問題

  1. 支出のリストから、負の値を除いて合計と平均を計算する。
  2. 多重ループで、1〜9の九九の表を表示する。
  3. ユーザーが空文字を入力するまで数字を尋ね、最後に最大値を表示する。
  4. リストの中で最初に1000より大きい数字を探し、なければその旨を表示する(for ... else を使う)。
  5. match で add、del、list のコマンドを解釈する。

まとめ

Pythonのループは、基本的に2つの文です。for はコレクションや range() の要素を順に処理し、while は条件が真の間繰り返します。break と continue で流れを制御し、enumerate() と zip() は手作業のカウンタを不要にし、if/elif/else と match/case が判断を担当します。これらの道具はすべて、講座の家計簿ツールを題材にした講義で実際に使いながら解説しています。

よくある質問

Pythonのforとwhileの違いは何ですか?

forは用意された並びを順に処理し、いつ終わるかを自分で把握しています。whileは条件が真の間繰り返します。回数が決まっているか、コレクションを回すならfor、何かの出来事を待つならwhileを選びましょう。

ループを逆順に回すにはどうすればよいですか?

コレクションなら reversed(items)、数字なら range(n - 1, -1, -1) を使います。reversed はリストをコピーせず、後ろから読み進めます。

Pythonにswitch文はありますか?

独立したswitch文はありません。その役割は if/elif の連なりと、Python 3.10で導入された match/case が担います。matchはリストや辞書を形で分解し、値を取り出すこともできるため、より多くのことができます。

ループと内包表記のどちらが速いですか?

[x * 2 for x in items] のような内包表記は、同じ処理をappendで書いたループより少し速く、短く書けます。複数の条件を含む複雑な処理は、通常のループの方が読みやすいでしょう。

二重ループを一度に抜けるにはどうすればよいですか?

breakは内側のループだけを抜けます。ループを関数に入れ、returnで抜けるのが簡単です。

動画でこのテーマを学ぶ

このテーマはコース「Python 3.15: от новичка до профи」で実践とともに詳しく解説しています。

コースへ