コンテンツにスキップ

制御構文

この章で学ぶこと

  • if / elif / else による条件分岐
  • for ループによる繰り返し処理(range、リストの走査)
  • while ループによる繰り返し処理
  • breakcontinue によるループ制御
  • ネスト(入れ子)されたループ
  • 初心者が陥りやすい間違いとその対策

条件分岐(if 文)

条件分岐とは、条件に応じて実行する処理を切り替える仕組みです。

基本構文

if 条件式:
    # 条件式が True のときに実行される処理
    処理

インデント(字下げ)が重要

Python ではインデント(通常はスペース 4 個)でブロック(処理のまとまり)を表します。インデントがずれるとエラーになるので注意してください。C 言語や Java のような波括弧 {} は使いません。

if のみ

score = 80

if score >= 60:
    print("合格です")  # score が 60 以上なので実行される

if-else

条件が成り立たない場合の処理を else で記述します。

score = 45

if score >= 60:
    print("合格です")
else:
    print("不合格です")  # score が 60 未満なので、こちらが実行される

if-elif-else

3 つ以上の分岐がある場合は elif(else if の略)を使います。

score = 75

if score >= 90:
    print("評価: A")
elif score >= 80:
    print("評価: B")
elif score >= 70:
    print("評価: C")   # score は 75 なので、ここが実行される
elif score >= 60:
    print("評価: D")
else:
    print("評価: F")

条件は上から順に評価される

if-elif-else では、上から順に条件が評価され、最初に True になった分岐だけが実行されます。一度条件が成立すると、残りの elif / else は評価されません。

条件式の組み合わせ

論理演算子 and, or, not を使って複数の条件を組み合わせることができます。

age = 20
is_member = True

# and: 両方とも満たす場合
if age >= 18 and is_member:
    print("会員特典を利用できます")

# or: どちらか一方を満たす場合
if age < 12 or age >= 65:
    print("割引が適用されます")

# not: 条件の否定
if not is_member:
    print("会員登録をおすすめします")

実行例

>>> x = 15
>>> if x > 10:
...     print("10より大きい")
... else:
...     print("10以下")
...
10より大きい
>>> x = 0
>>> if x > 0:
...     print("正")
... elif x < 0:
...     print("負")
... else:
...     print("ゼロ")
...
ゼロ

よくある間違い

1. if 文の末尾のコロン : を忘れる:

# 間違い: コロンが抜けている
# if score >= 60
#     print("合格")  # SyntaxError: expected ':'

# 正しい: コロンをつける
if score >= 60:
    print("合格")

2. 条件式で = を使ってしまう(== の代わりに):

x = 10

# 間違い: = は代入なので条件式に使えない
# if x = 10:  # SyntaxError

# 正しい: == で比較する
if x == 10:
    print("x は 10 です")

3. インデントの不一致:

# 間違い: 同じブロック内でインデントが揃っていない
# if score >= 60:
#     print("合格です")
#       print("おめでとう")  # IndentationError

# 正しい: 同じブロックのインデントは揃える
if score >= 60:
    print("合格です")
    print("おめでとう")

4. 条件の範囲指定を間違える:

score = 75

# 間違い: elif を使わず if だけで書くと、複数の条件が実行されうる
if score >= 90:
    print("A")
if score >= 70:      # 75 >= 70 なので、ここも実行される
    print("C")
if score >= 60:      # 75 >= 60 なので、ここも実行される
    print("D")
# 出力: C と D の両方が表示されてしまう

# 正しい: elif を使って排他的な分岐にする
if score >= 90:
    print("A")
elif score >= 70:
    print("C")      # ここだけが実行される
elif score >= 60:
    print("D")

for ループ

for ループは、決められた回数だけ処理を繰り返すときに使います。

range を使ったループ

range() 関数は連続する整数の列を生成します。

# 0 から 4 まで(5 は含まない)の繰り返し
for i in range(5):
    print(i)
# 出力: 0, 1, 2, 3, 4(1 行ずつ表示される)

range() の使い方のバリエーション:

# range(開始, 終了): 開始から終了-1 まで
for i in range(2, 6):
    print(i)
# 出力: 2, 3, 4, 5

# range(開始, 終了, ステップ): ステップ刻みで繰り返す
for i in range(0, 10, 2):
    print(i)
# 出力: 0, 2, 4, 6, 8

# 逆順のカウント
for i in range(5, 0, -1):
    print(i)
# 出力: 5, 4, 3, 2, 1

よくある間違い

range の終了値は含まれない(off-by-one エラー):

# 間違い: 1 から 5 まで表示したいのに 5 が含まれない
for i in range(1, 5):
    print(i)
# 出力: 1, 2, 3, 4(5 が出ない!)

# 正しい: 終了値を 1 つ大きくする
for i in range(1, 6):
    print(i)
# 出力: 1, 2, 3, 4, 5

range(n) は 0 から始まる:

# range(5) は 0, 1, 2, 3, 4 を生成する
# 1 からカウントしたい場合は range(1, 6) とする

range() の引数まとめ

書き方 生成される値 説明
range(5) 0, 1, 2, 3, 4 0 から 4 まで
range(2, 6) 2, 3, 4, 5 2 から 5 まで
range(0, 10, 2) 0, 2, 4, 6, 8 0 から 8 まで 2 刻み
range(5, 0, -1) 5, 4, 3, 2, 1 5 から 1 まで逆順
range(0) (空) 何も生成しない

リストの走査

リスト(配列)の要素を 1 つずつ取り出して処理できます。

fruits = ["りんご", "みかん", "ぶどう"]

for fruit in fruits:
    print(fruit)
# 出力:
# りんご
# みかん
# ぶどう

enumerate でインデックスと値を同時に取得

fruits = ["りんご", "みかん", "ぶどう"]

for i, fruit in enumerate(fruits):
    print(f"{i}: {fruit}")
# 出力:
# 0: りんご
# 1: みかん
# 2: ぶどう

インデックスが必要なときは enumerate を使おう

リストの要素を処理するときにインデックスも必要な場合、range(len(...)) よりも enumerate() を使う方が Python らしい書き方です。

fruits = ["りんご", "みかん", "ぶどう"]

# 推奨しない書き方
for i in range(len(fruits)):
    print(f"{i}: {fruits[i]}")

# 推奨する書き方
for i, fruit in enumerate(fruits):
    print(f"{i}: {fruit}")

実践例: 合計と平均を計算する

scores = [85, 72, 90, 68, 95]

total = 0
for score in scores:
    total += score  # total = total + score と同じ

average = total / len(scores)
print(f"合計: {total}")      # 合計: 410
print(f"平均: {average}")    # 平均: 82.0

よくある間違い

for 文の末尾にコロン : を忘れる:

# 間違い: コロンが抜けている
# for i in range(5)  # SyntaxError: expected ':'
#     print(i)

# 正しい:
for i in range(5):
    print(i)

ループ中にリストを変更する:

# 間違い: ループ中にリストから要素を削除する
numbers = [1, 2, 3, 4, 5]
for num in numbers:
    if num % 2 == 0:
        numbers.remove(num)  # ループ中の変更は予測不能な結果を招く
print(numbers)  # [1, 3, 5] ではなく予期しない結果になりうる

# 正しい方法 1: 新しいリストを作る
numbers = [1, 2, 3, 4, 5]
odd_numbers = [num for num in numbers if num % 2 != 0]
print(odd_numbers)  # [1, 3, 5]

# 正しい方法 2: コピーに対してループする
numbers = [1, 2, 3, 4, 5]
for num in numbers[:]:  # スライスでコピーを作る
    if num % 2 == 0:
        numbers.remove(num)
print(numbers)  # [1, 3, 5]

while ループ

while ループは、条件が True の間、処理を繰り返します。繰り返し回数が事前にわからない場合に使います。

基本構文

count = 0

while count < 5:
    print(count)
    count += 1  # カウンタを更新しないと無限ループになる
# 出力: 0, 1, 2, 3, 4

よくある間違い

無限ループ -- カウンタ変数の更新を忘れる:

# 間違い: count を更新していない → 無限ループ
count = 0
while count < 5:
    print(count)
    # count += 1 を書き忘れている!
# プログラムが永遠に止まらない → Ctrl + C で強制終了

# 正しい: ループ内で条件が変わるように更新する
count = 0
while count < 5:
    print(count)
    count += 1  # 必ず更新する

条件が常に True になってしまう:

# 間違い: 条件の方向が逆
count = 10
while count > 0:
    print(count)
    count += 1  # 増え続けるので永遠に count > 0 のまま

# 正しい:
count = 10
while count > 0:
    print(count)
    count -= 1  # 減らすことで条件が False になる

もし無限ループに陥ったら、Ctrl + C で強制終了できます。

実践例: 入力を繰り返し受け取る

# ユーザーが "quit" と入力するまで繰り返す
while True:
    text = input("メッセージを入力(quit で終了): ")
    if text == "quit":
        print("終了します")
        break  # ループを抜ける
    print(f"入力されたメッセージ: {text}")

実践例: 数当てゲーム

import random

# 1 から 100 までのランダムな数を生成
answer = random.randint(1, 100)
attempts = 0

print("1 から 100 までの数を当ててください")

while True:
    guess = int(input("予想を入力: "))
    attempts += 1

    if guess == answer:
        print(f"正解! {attempts} 回で当たりました")
        break
    elif guess < answer:
        print("もっと大きい数です")
    else:
        print("もっと小さい数です")

break と continue

break: ループを途中で抜ける

break を使うと、ループの途中で強制的にループを終了できます。

# リストから特定の値を探す
numbers = [3, 7, 2, 9, 5, 1]

for num in numbers:
    if num == 9:
        print("9 が見つかりました!")
        break  # 見つかったらループを終了
    print(f"{num} を確認中...")
# 出力:
# 3 を確認中...
# 7 を確認中...
# 2 を確認中...
# 9 が見つかりました!

continue: 残りの処理をスキップして次の繰り返しへ

continue を使うと、現在の繰り返しの残りの処理をスキップし、次の繰り返しに進みます。

# 偶数だけを表示する
for i in range(10):
    if i % 2 != 0:
        continue  # 奇数の場合、以降の処理をスキップ
    print(i)
# 出力: 0, 2, 4, 6, 8

for-else 構文

Python には for-else という独自の構文があります。for ループが break されずに最後まで回った場合に else ブロックが実行されます。

# リストに特定の値が含まれているか調べる
numbers = [3, 7, 2, 5, 1]

for num in numbers:
    if num == 9:
        print("9 が見つかりました")
        break
else:
    # break されなかった場合(= 9 が見つからなかった場合)
    print("9 は見つかりませんでした")
# 出力: 9 は見つかりませんでした

ネストされたループ

ループの中にループを入れることをネスト(入れ子)と言います。

九九の表を作る

for i in range(1, 10):
    for j in range(1, 10):
        # end=" " で改行せずにスペース区切りで出力
        print(f"{i * j:3d}", end=" ")
    print()  # 内側のループが終わったら改行

出力:

  1   2   3   4   5   6   7   8   9 
  2   4   6   8  10  12  14  16  18 
  3   6   9  12  15  18  21  24  27 
  ...

f-string の書式指定

{i * j:3d} は「整数を 3 桁の幅で右詰めに表示する」という意味です。これにより数字の桁が揃い、表が見やすくなります。

実践例: 二次元リストの走査

# 3x3 の二次元リスト(行列)
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# すべての要素を走査する
for row in matrix:
    for value in row:
        print(value, end=" ")
    print()
# 出力:
# 1 2 3
# 4 5 6
# 7 8 9

for と while の使い分け

状況 推奨するループ
繰り返し回数が決まっている for
リストや文字列の要素を 1 つずつ処理する for
繰り返し回数が事前にわからない while
条件が満たされるまで繰り返す while
ユーザー入力を繰り返し受け取る while

Python では for が多く使われる

Python では、リストや range などのイテラブル(繰り返し可能なオブジェクト)を使った for ループが一般的です。C 言語のように while でカウンタ変数を手動管理するよりも、for を使う方がシンプルで読みやすいコードになります。


よくある間違いのまとめ

よくある間違い

1. コロン : の付け忘れ(if / for / while すべて共通):

# 間違い
# if x > 0       # SyntaxError
# for i in range(5)  # SyntaxError
# while x > 0    # SyntaxError

# 正しい: 必ずコロンをつける
if x > 0:
    print(x)
for i in range(5):
    print(i)
while x > 0:
    x -= 1

2. インデントの問題:

# 間違い: if の中の処理がインデントされていない
# if True:
# print("hello")  # IndentationError

# 間違い: インデントがタブとスペースの混在
# (エディタの設定でスペース 4 個に統一すること)

# 正しい:
if True:
    print("hello")  # スペース 4 個でインデント

3. range() の off-by-one エラー:

# 「1 から 10 まで」を処理したい場合
# 間違い:
for i in range(1, 10):  # 10 が含まれない(1〜9)
    print(i)

# 正しい:
for i in range(1, 11):  # 11 を指定することで 1〜10 になる
    print(i)

4. while の条件更新忘れによる無限ループ:

# 間違い:
i = 0
while i < 10:
    print(i)
    # i += 1 を忘れている → 永遠に 0 を出力

# 正しい:
i = 0
while i < 10:
    print(i)
    i += 1

5. ループ中にリストを変更する:

# 間違い: ループ中にリストのサイズを変える
items = [1, 2, 3, 4, 5]
for item in items:
    if item == 3:
        items.remove(item)  # 予期しない動作の原因
# items は [1, 2, 4, 5] になるが、4 がスキップされることがある

# 正しい: リスト内包表記で新しいリストを作る
items = [1, 2, 3, 4, 5]
items = [item for item in items if item != 3]
# items は [1, 2, 4, 5]

まとめ

  • if / elif / else で条件に応じて処理を分岐する。末尾のコロン : を忘れないこと
  • for ループrange() やリストを使って決まった回数の繰り返しに適している
  • range() の終了値は含まれない(例: range(5) は 0, 1, 2, 3, 4)
  • while ループ は条件が True の間繰り返し、回数が不定の場合に使う。カウンタの更新忘れに注意
  • break はループを途中で終了し、continue は残りの処理をスキップして次の繰り返しに進む
  • ループの中にループを入れるネストで、二次元的な処理を実現できる
  • Python ではインデントがブロック構造を表すため、正しいインデントが不可欠
  • ループ中にリストを変更すると予期しない動作になるため、新しいリストを作るようにする