制御構文¶
この章で学ぶこと¶
if/elif/elseによる条件分岐forループによる繰り返し処理(range、リストの走査)whileループによる繰り返し処理breakとcontinueによるループ制御- ネスト(入れ子)されたループ
- 初心者が陥りやすい間違いとその対策
条件分岐(if 文)¶
条件分岐とは、条件に応じて実行する処理を切り替える仕組みです。
基本構文¶
インデント(字下げ)が重要
Python ではインデント(通常はスペース 4 個)でブロック(処理のまとまり)を表します。インデントがずれるとエラーになるので注意してください。C 言語や Java のような波括弧 {} は使いません。
if のみ¶
if-else¶
条件が成り立たない場合の処理を else で記述します。
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() 関数は連続する整数の列を生成します。
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() の引数まとめ¶
| 書き方 | 生成される値 | 説明 |
|---|---|---|
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 つずつ取り出して処理できます。
enumerate でインデックスと値を同時に取得¶
fruits = ["りんご", "みかん", "ぶどう"]
for i, fruit in enumerate(fruits):
print(f"{i}: {fruit}")
# 出力:
# 0: りんご
# 1: みかん
# 2: ぶどう
インデックスが必要なときは enumerate を使おう
リストの要素を処理するときにインデックスも必要な場合、range(len(...)) よりも enumerate() を使う方が Python らしい書き方です。
実践例: 合計と平均を計算する¶
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 を更新していない → 無限ループ
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() # 内側のループが終わったら改行
出力:
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. ループ中にリストを変更する:
まとめ¶
- if / elif / else で条件に応じて処理を分岐する。末尾のコロン
:を忘れないこと - for ループ は
range()やリストを使って決まった回数の繰り返しに適している range()の終了値は含まれない(例:range(5)は 0, 1, 2, 3, 4)- while ループ は条件が
Trueの間繰り返し、回数が不定の場合に使う。カウンタの更新忘れに注意 - break はループを途中で終了し、continue は残りの処理をスキップして次の繰り返しに進む
- ループの中にループを入れるネストで、二次元的な処理を実現できる
- Python ではインデントがブロック構造を表すため、正しいインデントが不可欠
- ループ中にリストを変更すると予期しない動作になるため、新しいリストを作るようにする