【Python入門シリーズ⑤】繰り返し処理でプログラムを自動化する

python入門

こんにちは!前回の【Python入門シリーズ④】では条件分岐について学習しました。今回は繰り返し処理について詳しく解説していきます。繰り返し処理は「同じ作業を何度も実行する」ことをプログラムに自動でやらせる機能で、プログラミングの最も強力な武器の一つです。手作業なら何時間もかかる単純作業も、繰り返し処理を使えば一瞬で終わらせることができます! ここまでできるようになったらプログラムしてる感出てきますね笑

このシリーズの目次

このシリーズでは、プログラミングの基礎から始めて、最終的にはAI・機械学習の初歩までを体験できるような構成になっています。

繰り返し処理とは何か?

繰り返し処理(ループ処理)とは、同じ処理を複数回実行する仕組みです。日常生活でも「毎朝歯を磨く」「1週間毎日ジョギングする」のように繰り返し行動を自然に行っていますね。

プログラミングにおける繰り返し処理の威力を実感してみましょう。例えば「1から100までの数字を画面に表示する」という作業を考えてみてください。繰り返し処理を使わなければ、こんなコードになります:

print(1)
print(2)
print(3)
# ...延々と続く...
print(98)
print(99)
print(100)
Python

これを100行も書くのは大変ですし、間違いも起こりやすいですよね。繰り返し処理を使えば、わずか2行で同じことができます:

for i in range(1, 101):
    print(i)
Python

このように、繰り返し処理を使うことで:

  • コードが短く、読みやすくなる
  • 間違いが減る(同じコードを何度も書かなくて済む)
  • 変更が簡単になる(1箇所直せば全体に反映される)
  • 処理の回数を動的に変更できる(100回を1000回に変更するのも簡単)

今回の記事では演算子を多用します!参考になる記事、演算子の復習はこちら↓↓

Pythonの演算子一覧まとめ|基本から知らないと損する演算子まで解説!

for文の基本構文

Pythonには主に2種類の繰り返し処理があります。まずはfor文から見ていきましょう。for文は「決まった回数」または「決まった要素」に対して繰り返し処理を行う時に使います。

リストの要素を順番に処理する

for文の最も基本的な使い方は、リストなどの要素を順番に取り出して処理することです。

fruits = ["りんご", "バナナ", "オレンジ"]

for fruit in fruits:
    print(f"{fruit}が好きです")
Python

このコードを実行すると、以下のように表示されます:

りんごが好きです
バナナが好きです
オレンジが好きです

構文のポイント:

  • for 変数名 in リストなど: という形で書く
  • :(コロン)の後の処理はインデント(字下げ)する
  • ループのたびに、リストから次の要素が変数に代入される
  • リストの最後まで到達したらループが終了する

変数名は何でも構いませんが、通常は要素の内容を表す分かりやすい名前を付けます。上の例では、果物のリスト(fruits)から一つずつ取り出すので、単数形のfruitという変数名を使っています。

文字列の各文字を処理する

Pythonでは文字列も文字の集まりとして扱えるので、for文で1文字ずつ取り出すことができます。

message = "Python"

for char in message:
    print(f"文字: {char}")
Python

このコードは “P”, “y”, “t”, “h”, “o”, “n” を一文字ずつ順番に表示します。この性質を利用すると、文字列の分析や加工を簡単に行うことができます。

文字: P
文字: y
文字: t
文字: h
文字: o
文字: n

こんな感じの実行結果ですね!

range関数で数値の繰り返し

「特定の回数だけ処理を繰り返したい」という場合、range()関数が非常に便利です。range関数は数値の連続を生成する関数で、for文との組み合わせで威力を発揮します。

range関数の基本的な使い方

range関数には3つの使い方があります:

1. range(終了値) – 0から始まる連続した数値

for i in range(5):
    print(i)
# 出力: 0, 1, 2, 3, 4
Python

この形式では、0から始まり、指定した終了値の手前までの数値が生成されます。range(5)なら0, 1, 2, 3, 4の5個の数値です。5は含まれない点に注意しましょう。

2. range(開始値, 終了値) – 開始位置を指定

for i in range(10, 15):
    print(i)
# 出力: 10, 11, 12, 13, 14
Python

この形式では、開始値から終了値の手前までの数値が生成されます。range(10, 15)なら10, 11, 12, 13, 14です。

3. range(開始値, 終了値, ステップ) – 増加量を指定

for i in range(0, 10, 2):
    print(i)
# 出力: 0, 2, 4, 6, 8
Python

ステップを指定すると、その間隔で数値が生成されます。range(0, 10, 2)は2ずつ増加するので、偶数だけが取り出されます。

逆順の繰り返しも可能です:

for i in range(10, 0, -1):
    print(i)
# 出力: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
Python

ステップに負の値を指定すると、数値が減少していきます。これはカウントダウンなどを実装する時に便利です。

rangeを使う理由

「なぜリストに直接数値を書かないのか?」と思うかもしれません。例えば[0, 1, 2, 3, 4]と書けば同じことができそうですよね。

しかし、range関数には大きな利点があります:

  1. メモリ効率が良い: range(1000000)としても、実際には100万個の数値をメモリに保存しません。必要な時に計算して生成するため、メモリをほとんど消費しません。
  2. コードが簡潔: range(1, 1001)と書くだけで1から1000まで表現できます。リストで書くと非常に長くなります。
  3. 変更が容易: 繰り返し回数を変更する時も、range関数の引数を変えるだけで済みます。

while文の基本構文

for文が「決まった回数や要素」を処理するのに対し、while文は「条件が満たされている間」繰り返し処理を続けます。終了条件がはっきりしていない場合や、ユーザーの入力によって繰り返しを制御したい場合に便利です。

while文の基本

count = 0

while count < 5:
    print(f"カウント: {count}")
    count += 1

print("終了しました")
Python

構文のポイント:

  • while 条件式: という形で書く
  • 条件式がTrueの間、処理を繰り返す
  • 条件式がFalseになったらループを抜ける
  • ループ内で条件を変化させる処理が必要(でないと無限ループになる)

上記のコードでは、countが0から始まり、ループのたびに1ずつ増えていきます。countが5になると条件count < 5Falseになり、ループが終了します。

while文とfor文の使い分け

どちらを使うべきか迷った時は、以下の基準で判断しましょう:

for文を使うべき場合:

  • 繰り返す回数が事前に分かっている
  • リストや文字列の各要素を処理したい
  • 0から10まで、のように決まった範囲の数値を扱う

while文を使うべき場合:

  • 繰り返す回数が事前に分からない
  • 「特定の条件が満たされるまで」処理を続けたい
  • ユーザー入力によって繰り返しを制御したい

実用例: ユーザー入力の繰り返し受付

while文の典型的な使用例として、ユーザーが特定の入力をするまで処理を続けるパターンがあります。

while True:
    answer = input("続けますか? (yes/no): ")
    
    if answer == "no":
        print("プログラムを終了します")
        break
    elif answer == "yes":
        print("処理を続けます")
    else:
        print("yes か no で答えてください")
Python

この例ではwhile True:という「常に真の条件」を使っているため、理論上は無限に繰り返されます。しかしbreak文を使うことで、ユーザーが”no”と入力した時にループから抜け出すことができます。

繰り返しの制御:breakとcontinue

繰り返し処理の流れを細かく制御できる2つの重要なキーワードがあります。

break文 – ループを途中で終了する

break文は、ループを即座に終了させます。これは「特定の条件が満たされたら、それ以上繰り返す必要がない」という場合に使います。

for i in range(1, 100):
    print(i)
    if i == 5:
        print("5に到達したので終了します")
        break
Python

このコードは1から99まで表示するように見えますが、実際には1から5までしか表示されません。iが5になった時点でbreakが実行され、forループ全体が終了します。

breakの実用例:

  • 検索処理で目的のデータが見つかった時に終了する
  • エラーが発生した時に処理を中断する
  • ユーザーが終了を選択した時にループを抜ける

continue文 – 現在の繰り返しをスキップする

continue文は、そのループの残りの処理をスキップして、次の繰り返しに進みます。「特定の条件の時だけ処理をスキップしたい」という場合に使います。

for i in range(1, 11):
    if i % 2 == 0:
        continue
    print(i)
Python

このコードは1から10までの数を処理しますが、偶数(i % 2 == 0)の時はcontinueが実行され、その下のprint(i)がスキップされます。結果として、奇数(1, 3, 5, 7, 9)だけが表示されます。

breakとcontinueの違い:

  • break: ループ全体を終了する(ループの外に出る)
  • continue: 今回の繰り返しだけをスキップして次の繰り返しへ進む(ループは継続)

実用例: データのフィルタリング

continueは不要なデータをスキップする時に便利です。

scores = [85, 42, 90, 55, 78, 30, 95]

print("60点以上の成績:")
for score in scores:
    if score < 60:
        continue  # 60点未満はスキップ
    print(f"{score}点")
Python

このコードは成績リストから60点以上のものだけを表示します。60点未満の成績に遭遇した時はcontinueでスキップされ、print文が実行されません。

ネストした繰り返し(二重ループ)

ループの中にさらにループを入れることを「ネスト(入れ子)」と呼びます。二次元的なデータ処理や、複雑なパターン生成に使われます。

基本的な二重ループ

for i in range(1, 4):
    for j in range(1, 4):
        print(f"i={i}, j={j}")
Python

このコードは以下のように出力されます:

i=1, j=1
i=1, j=2
i=1, j=3
i=2, j=1
i=2, j=2
i=2, j=3
i=3, j=1
i=3, j=2
i=3, j=3

動作の仕組み:

  1. 外側のループでiが1になる
  2. 内側のループでjが1, 2, 3と変化する
  3. 内側のループが終わったら、外側のループでiが2になる
  4. 再び内側のループでjが1, 2, 3と変化する
  5. これを繰り返す

つまり、外側のループが1回進むごとに、内側のループが完全に実行されます。

実用例: 九九の表

二重ループの実用的な例として、掛け算の九九表を作成してみましょう。

print("九九の表")
for i in range(1, 10):
    for j in range(1, 10):
        result = i * j
        print(f"{result:3}", end=" ")  # 3桁分のスペースで右寄せ
    print()  # 行の終わりで改行
Python

このコードは9×9のマトリクス状に九九の計算結果を表示します。外側のループが「段」を、内側のループが「列」を表しています。

ポイント:

  • print(f"{result:3}", end=" "):3は3桁分の幅で表示することを意味します(桁揃えのため)
  • end=" "で改行せずにスペースで区切ります
  • 内側のループが終わった後のprint()で改行し、次の段に移ります

注意点: ネストの深さ

ループをネストすると処理回数は掛け算で増えていきます:

  • 1重ループ: n回
  • 2重ループ: n × m回
  • 3重ループ: n × m × l回

例えば、それぞれ100回のループを3重にネストすると、100 × 100 × 100 = 1,000,000回の処理になります。ネストが深くなるほど処理時間が大幅に増えるので、本当に必要な場合にのみ使うようにしましょう。

実践的な例:データの集計処理

繰り返し処理は、大量のデータを処理する場面で真価を発揮します。データ分析の基本である「集計」を実装してみましょう。

平均値の計算

# 生徒の点数データ
scores = [78, 92, 85, 67, 88, 95, 73, 81, 90, 84]

# 合計を計算
total = 0
for score in scores:
    total += score

# 平均を計算
average = total / len(scores)

print(f"生徒数: {len(scores)}人")
print(f"合計点: {total}点")
print(f"平均点: {average:.1f}点")
Python

このプログラムでは、forループを使って各生徒の点数を順番にtotalに加算しています。すべての点数を足し終えたら、生徒数(リストの長さ)で割って平均を求めています。

処理の流れ:

  1. totalを0で初期化
  2. リストの各要素を順番に取り出す
  3. 取り出した値をtotalに加算
  4. すべての要素を処理したら、totalを要素数で割る

この単純なパターンは、売上の合計、気温の平均、アクセス数の集計など、様々な場面で応用できます。

条件付き集計

さらに実践的な例として、条件を満たすデータだけを集計してみましょう。

scores = [78, 92, 85, 67, 88, 95, 73, 81, 90, 84]

# 80点以上の成績を集計
high_scores = []
for score in scores:
    if score >= 80:
        high_scores.append(score)

print(f"80点以上の人数: {len(high_scores)}人")
print(f"80点以上の点数: {high_scores}")
print(f"80点以上の平均: {sum(high_scores) / len(high_scores):.1f}点")
Python

この例では、ループ内で条件分岐を使い、80点以上の成績だけを新しいリストhigh_scoresに追加しています。条件分岐と繰り返し処理を組み合わせることで、より複雑なデータ処理が可能になります。

実践的な例:パターン生成

繰り返し処理のもう一つの重要な用途は、規則的なパターンを生成することです。

星印で三角形を描く

height = 5

for i in range(1, height + 1):
    print("*" * i)
Python

出力:

*
**
***
****
*****

このコードでは、Pythonの文字列の特性を利用しています。"*" * iは「*」という文字列をi回繰り返すという意味です。ループが進むにつれてiが1, 2, 3…と増えていくため、星印の数も増えていきます。

ピラミッド型のパターン

もう少し複雑なパターンも作れます:

height = 5

for i in range(1, height + 1):
    spaces = " " * (height - i)
    stars = "*" * (2 * i - 1)
    print(spaces + stars)
Python

出力:

    *
   ***
  *****
 *******
*********

このコードでは、各行で以下の計算をしています:

  • 空白の数: height - i(上の行ほど多い)
  • 星印の数: 2 * i - 1(1, 3, 5, 7, 9…と増える)

繰り返し処理と算数的な計算を組み合わせることで、様々なパターンを生成できます。

AIとの関連性

繰り返し処理は、AI・機械学習においても中心的な役割を果たします。

学習プロセスでの繰り返し

機械学習モデルの学習は、基本的に繰り返し処理の連続です。モデルは大量のデータに対して何度も計算を繰り返すことで、徐々にパターンを学習していきます。

# 機械学習の学習ループの概念的な例
epochs = 100  # エポック数(全データを学習する回数)

for epoch in range(epochs):
    total_loss = 0
    
    # 各データサンプルに対して処理
    for data in training_data:
        # 予測を計算
        prediction = model.predict(data)
        # 誤差を計算
        loss = calculate_loss(prediction, data.label)
        # モデルを更新
        model.update(loss)
        total_loss += loss
    
    # 進捗を表示
    if epoch % 10 == 0:
        print(f"エポック {epoch}: 平均損失 = {total_loss / len(training_data):.4f}")
Python

この例は実際には動きませんが、機械学習の訓練プロセスの構造を示しています。外側のループで「何回全体を学習するか」を制御し、内側のループで「各データに対する処理」を行っています。

AIにおける繰り返し処理の役割:

  1. データの前処理: 大量の画像や文章データを1つずつ処理
  2. 学習の反復: 同じデータを何度も使って精度を向上
  3. バッチ処理: 複数のデータをまとめて効率的に処理
  4. ハイパーパラメータの探索: 様々な設定を試して最適なものを見つける

グリッドサーチ(パラメータ探索)

AIモデルの性能を最大化するため、様々なパラメータの組み合わせを試す「グリッドサーチ」でも二重ループが使われます:

# パラメータの候補
learning_rates = [0.001, 0.01, 0.1]
batch_sizes = [16, 32, 64]

best_accuracy = 0
best_params = {}

# すべての組み合わせを試す
for lr in learning_rates:
    for bs in batch_sizes:
        print(f"学習率: {lr}, バッチサイズ: {bs} で訓練中...")
        
        # モデルを訓練(概念的な例)
        accuracy = train_model(learning_rate=lr, batch_size=bs)
        
        # 最良の結果を記録
        if accuracy > best_accuracy:
            best_accuracy = accuracy
            best_params = {"learning_rate": lr, "batch_size": bs}

print(f"最良の精度: {best_accuracy:.2%}")
print(f"最良のパラメータ: {best_params}")
Python

このように、繰り返し処理は「試行錯誤を自動化する」という点でAI開発に不可欠です。

よくあるエラーとその対策

繰り返し処理を書く際によく遭遇するエラーを見ていきましょう。

IndentationError: expected an indented block

# ❌ このコードはエラーになります
for i in range(5):
print(i)  # インデントがない
Python

エラーメッセージ:

IndentationError: expected an indented block

原因と解決方法: for文やwhile文の中の処理は必ずインデント(字下げ)が必要です。Pythonではインデントで「どこからどこまでがループの中か」を判断します。

# ✅ 正しい書き方
for i in range(5):
    print(i)  # インデント(スペース4個)が必要
Python

無限ループ

# ❌ このコードは無限に繰り返されます
count = 0
while count < 5:
    print(count)
    # count += 1 が書かれていない!
Python

原因と解決方法: while文では、ループ内で条件を変化させる処理が必要です。上記の例ではcountが常に0のままなので、count < 5が永遠にTrueのままです。

# ✅ 正しい書き方
count = 0
while count < 5:
    print(count)
    count += 1  # 条件を変化させる
Python

もし無限ループに入ってしまった場合は、Ctrl + C(MacはCommand + C)でプログラムを強制終了できます。

NameError: name ‘i’ is not defined

# ❌ このコードはエラーになります
for i in range(5):
    print(i)

print(i)  # ループの外でiを使おうとしている
Python

このコードは実際にはエラーになりません(Python 3では、ループ変数はループ後も残ります)が、ループ変数をループの外で使うのは良い習慣ではありません。ループ変数は「そのループの中だけのもの」と考えましょう。

IndexError: list index out of range

# ❌ このコードはエラーになります
fruits = ["りんご", "バナナ", "オレンジ"]

for i in range(5):  # リストは3要素しかないのに5回繰り返す
    print(fruits[i])
Python

エラーメッセージ:

IndexError: list index out of range

原因と解決方法: リストに3つしか要素がないのに、5回繰り返そうとしているため、4番目と5番目でエラーが発生します。リストの要素数とループ回数を一致させる必要があります。

# ✅ 正しい書き方1: len()を使う
for i in range(len(fruits)):
    print(fruits[i])

# ✅ 正しい書き方2: 直接要素を取り出す(推奨)
for fruit in fruits:
    print(fruit)
Python

一般的に、リストの各要素を処理したい場合は、インデックスを使うよりも直接要素を取り出す方がシンプルで安全です。

SyntaxError: invalid syntax(コロン忘れ)

# ❌ このコードはエラーになります
for i in range(5)  # コロンがない
    print(i)
Python

エラーメッセージ:

SyntaxError: invalid syntax

原因と解決方法: for文やwhile文の条件の後には必ず:(コロン)が必要です。コロンは「ここから新しいブロックが始まる」という合図です。

# ✅ 正しい書き方
for i in range(5):  # コロンを忘れずに
    print(i)
Python

練習問題

以下の問題に挑戦して、繰り返し処理の理解を深めましょう!

問題1: 階乗の計算

ユーザーが入力した数の階乗を計算するプログラムを作成してください。階乗とは、1からその数までのすべての整数を掛け合わせたものです。

例: 5の階乗 = 5 × 4 × 3 × 2 × 1 = 120

ヒント:

  • 結果を保存する変数を1で初期化する
  • range()を使って1からnまでの数を順番に掛ける

問題2: 数当てゲーム

1から100までのランダムな数をコンピュータが決め、ユーザーが当てるゲームを作成してください。ユーザーが予想を入力すると「もっと大きい」「もっと小さい」「正解!」のヒントを表示し、正解するまで繰り返します。

ヒント:

  • import randomしてrandom.randint(1, 100)でランダムな整数を生成
  • while文で正解するまで繰り返す
  • 試行回数をカウントして最後に表示する

問題3: 素数の判定と一覧表示

ユーザーが入力した数までの素数をすべて表示するプログラムを作成してください。素数とは、1とその数自身以外では割り切れない数(2, 3, 5, 7, 11…)のことです。

ヒント:

  • 外側のループで2から入力値までの各数をチェック
  • 内側のループで、その数が他の数で割り切れるかを確認
  • 割り切れなければ素数として表示

問題4: パスワード強度チェック

ユーザーが入力したパスワードの強度を以下の基準でチェックし、満たしていない条件を指摘するプログラムを作成してください:

  • 8文字以上
  • 少なくとも1つの数字を含む
  • 少なくとも1つの大文字を含む
  • 少なくとも1つの小文字を含む

ヒント:

  • for文でパスワードの各文字をチェック
  • char.isdigit(), char.isupper(), char.islower()メソッドを使用
  • フラグ変数(True/False)で各条件の達成状況を管理

問題5: 九九の暗記チェック

九九の問題をランダムに出題し、ユーザーが正解するまで繰り返すプログラムを作成してください。10問連続で正解したら終了し、正解率を表示します。

ヒント:

  • 二重ループまたはランダムな2つの数(1〜9)を生成
  • ユーザーの答えと正解を比較
  • 正解数と問題数をカウントして正解率を計算

まとめ

今回は繰り返し処理について学習しました。重要なポイントをおさらいします:

for文

  • リストや範囲の各要素に対して処理を実行
  • 繰り返す回数が決まっている場合に適している
  • for 変数 in リスト:という構文
  • range()関数で数値の連続を生成できる

while文

  • 条件が真の間、処理を繰り返す
  • 繰り返す回数が事前に分からない場合に適している
  • while 条件式:という構文
  • 必ずループ内で条件を変化させる処理が必要(無限ループに注意)

制御文

  • break: ループを即座に終了する
  • continue: 今回の繰り返しをスキップして次へ進む

ネスト(入れ子)

  • ループの中にループを入れることができる
  • 二次元的なデータ処理やパターン生成に便利
  • 処理回数は掛け算で増えるため、パフォーマンスに注意

実用的な応用

  • データの集計(合計、平均、カウント)
  • パターンやテキストの生成
  • データのフィルタリングと変換
  • AI/機械学習での学習プロセス

繰り返し処理をマスターすると、手作業では不可能な大量のデータ処理や、複雑な計算をプログラムに任せることができます。これはプログラミングの最も強力な機能の一つです!

次回予告

第6回では「関数を作ってコードを整理整頓する」として、コードを部品化して再利用しやすくする方法を学習します。繰り返し処理と組み合わせることで、さらに効率的で読みやすいプログラムが書けるようになります。お楽しみに!


関連記事:

コメント

タイトルとURLをコピーしました