Q1次のコードの実行結果はどれですか?for i in range(2, 6):
print(i)
for ループと range / enumerate / zip
Python の for ループを基礎から解説します。range / enumerate / zip と break / continue によるループ制御まで図解で押さえます。
ここまでで if / elif による分岐と、all() / any() による一括判定を学びました。
この記事では、同じ処理をリストの全要素に対して繰り返すための for 文を身につけます。if と for の 2 つが揃えば、ほとんどの実務的な処理は書けます。
for でコレクションを 1 要素ずつ取り出す
for 文は、リスト・タプル・文字列・辞書などの反復可能なオブジェクト(イテラブル)から、要素を先頭から 1 つずつ取り出し、指定した変数に入れて処理を繰り返す構文です。
基本形は for 変数 in イテラブル: の 1 行と、4 スペースでインデントしたブロックです。
コレクションから 1 要素取り出す→変数に代入→ブロックを実行→次の要素へ、という流れを要素が尽きるまで繰り返します。
# リストをループ
fruits = ["apple", "banana", "orange"]
for fruit in fruits:
print(fruit)
# 出力:
# apple
# banana
# orange
# 文字列も反復可能(イテラブル)(1 文字ずつ取り出される)
for ch in "ABC":
print(ch)
# A / B / C が順に出力される
コロンと 4 スペースインデントを忘れずに
for の行末には必ず :(コロン)、ブロックの各行は 4 スペース(または 1 タブ)インデント。インデントが揃っていないと IndentationError になります。
辞書を for でループする
辞書をそのまま for に渡すと、キーだけが順に取り出されます。値も一緒に欲しいときは .items() を使うのが一般的です。値だけで十分なら .values() を使います。
| 書き方 | 取り出されるもの | 典型的な用途 |
|---|---|---|
| for key in 辞書: | キー | キーだけで十分なとき |
| for value in 辞書.values(): | 値 | 値だけ使って集計したいとき |
| for key, value in 辞書.items(): | キーと値のペア | 両方を使って整形表示・判定したいとき |
user = {"name": "tanaka", "age": 29, "role": "admin"}
# キーだけ
for key in user:
print(key)
# name / age / role
# 値だけ
for value in user.values():
print(value)
# tanaka / 29 / admin
# キーと値を同時に
for key, value in user.items():
print(f"{key}: {value}")
# name: tanaka / age: 29 / role: admin
range() で決まった回数だけ繰り返す
range(n) は 0 から n-1 までの整数列を返すビルトイン関数で、for と組み合わせて決まった回数の繰り返しを書くときによく使います。引数の渡し方は 3 通りあります。
| 書き方 | 生成される値 | 用途 |
|---|---|---|
| range(5) | 0, 1, 2, 3, 4 | 0 から n-1 までの連番 |
| range(2, 8) | 2, 3, 4, 5, 6, 7 | 開始と終了を指定(終了は含まない) |
| range(1, 10, 2) | 1, 3, 5, 7, 9 | 開始・終了・ステップ幅を指定 |
# 0 〜 4 をループ
for i in range(5):
print(i)
# 0 1 2 3 4 の 5 回出力
# 2 〜 7
for i in range(2, 8):
print(i)
# 1 〜 9 を 2 刻み
for i in range(1, 10, 2):
print(i)
# カウンタを使わず「10 回同じ処理」だけしたいときは _ を使う
for _ in range(3):
print("retry...")
ループ変数名を _(アンダースコア)にするのは 「中で使わない変数」だとすぐ伝えるための慣習です。i や j にしても動きますが、「使われていないのに意味があるのか?」と読み手を迷わせるので、回数だけ欲しい場合は _ と覚えておきましょう。
enumerate と zip でインデックス・複数リストに対応する
実務では、何番目の要素かも欲しい場合や、複数のリストを並行して回したい場合がよくあります。enumerate() と zip() を使うとコードが一気に短く、読みやすくなります。
enumerate() — 番号付きでループ
enumerate(リスト) を for に渡すと、インデックスと要素のペアが順に取り出せます。順位表示やエラーメッセージの行番号など、「何番目か」を併記したいときに便利です。
products = ["apple", "bread", "milk"]
for index, name in enumerate(products):
print(f"{index}: {name}")
# 0: apple
# 1: bread
# 2: milk
# 1 始まりにしたいときは第 2 引数で開始番号を指定
for rank, name in enumerate(products, 1):
print(f"{rank} 位: {name}")
# 1 位: apple / 2 位: bread / 3 位: milk
zip() — 複数リストを同時に回す
zip(リスト1, リスト2, ...) を使うと、複数のリストから同じインデックスの要素を一緒に取り出せます。短い方のリストに合わせて終了するので、長さが違っても安全です。
names = ["tanaka", "yamada", "suzuki"]
scores = [82, 91, 65]
for name, score in zip(names, scores):
print(f"{name}: {score} 点")
# tanaka: 82 点 / yamada: 91 点 / suzuki: 65 点
break と continue でループを制御する
ループ中に「もう見つかったから終わりたい」「この回だけスキップしたい」というケースはよくあります。前者は break で即座にループを抜け、後者は continue でその回の残りをスキップして次の要素に進みます。
break はループそのものを終わらせるので、その後の要素は一切評価されません。一方 continue は今回の残りをスキップして次の要素へ進むだけで、ループ全体は続きます。どちらも if の中で呼び出されるのが定石です。
# break:目的のものが見つかった時点で終了
users = ["tanaka", "yamada", "suzuki", "kato"]
for name in users:
if name == "suzuki":
print("見つけました")
break
print(f"確認中: {name}")
# 確認中: tanaka / 確認中: yamada / 見つけました
# continue:0 点は集計から除外してスキップ
scores = [80, 0, 65, 0, 91]
total = 0
for score in scores:
if score == 0:
continue
total += score
print(total) # 80 + 65 + 91 = 236
この記事では、for 文の全体像として、リスト・辞書のイテレーション、range() による回数ループ、enumerate() / zip() による拡張、break / continue によるループ制御を学びました。
次の記事では、回数が事前に分からない繰り返しで使う while ループと、そこでとくに気をつけたい無限ループの回避を見ていきます。
理解度チェック
まずは1問ずつ答えてみましょう。
Q2enumerate(['a', 'b', 'c'], 1) を for で展開すると、何のペアが取り出されますか?
Q3次のコードの実行結果はどれですか?nums = [1, 2, 3, 4, 5]
for n in nums:
if n == 3:
continue
print(n)