C
Python/中級/Lesson 11

ジェネレーター (Generator)

1時間·theory
このチャプター
3/8
Python

ジェネレーター (Generator)

🎯 このlessonを読み終えたら

このlessonを読み終えると、以下の3つを自信を持ってできるようになります。

  • yield が関数をジェネレーターに変えるメカニズム
  • ✅ メモリ効率(大きなlistの代わりにgenerator)
  • itertools の活用(chain、islice、groupby)

学習目標をチェックリストとして持ち、すべて答えられるようになったらlessonを閉じましょう。

generatorの5つのポイント — コード + 実行結果

generator = 値を1つずつ遅延生産する関数。メモリ節約 + 無限シーケンスが可能。

💻 悪い例 — 大量データをリストとして一度にメモリに読み込む
# 1億個の数字をリストで — メモリ数GB消費
def get_all_numbers(n):
    result = []
    for i in range(n):
        result.append(i * i)
    return result  # すべての値がメモリに存在

# 呼び出し時に即座に数GBメモリ使用
numbers = get_all_numbers(100_000_000)
for num in numbers:
    process(num)
💻 良い例 — yieldによる遅延評価
from typing import Generator, Iterator
import sys

# ジェネレーター関数 — 値を1つずつ生成 (メモリ O(1))
def square_numbers(n: int) -> Generator[int, None, None]:
    """n個の平方数を1つずつ生成"""
    for i in range(n):
        yield i * i  # 呼び出し元に値を返した後、ここで一時停止

# ジェネレーター式 — より簡潔
squares = (i * i for i in range(100_000_000))

print(sys.getsizeof(list(range(1000))))    # ~8056 bytes
print(sys.getsizeof(range(1000)))          # 48 bytes (イテレーター)
print(sys.getsizeof(squares))             # 104 bytes (ジェネレーター)

# yield from — 内部イテラブル委任
def flatten(nested: list) -> Generator:
    for item in nested:
        if isinstance(item, list):
            yield from flatten(item)  # 再帰委任
        else:
            yield item

print(list(flatten([1, [2, [3, 4]], 5])))  # [1, 2, 3, 4, 5]

# 実践: 大容量CSVファイル処理
def read_large_csv(filepath: str) -> Iterator[dict]:
    """メモリ効率的に大容量CSV処理"""
    import csv
    with open(filepath, encoding='utf-8') as f:
        reader = csv.DictReader(f)
        for row in reader:
            yield row  # 1行ずつ処理、メモリ O(1)

# データパイプライン組み合わせ
def process_pipeline(filepath: str):
    rows = read_large_csv(filepath)
    filtered = (row for row in rows if int(row['age']) >= 18)  # フィルター
    transformed = ({**row, 'name': row['name'].upper()} for row in filtered)  # 変換
    for item in transformed:  # 遅延実行
        save_to_db(item)

🐍 実際に動かしてみよう — ジェネレーター (Generator)

上記の概念を実際のコードで実行してみてください。値を変えながらどう動くかを直接確認するのが、最も速い学習法です。
✏️ Python 코드
📟 コンソール出力
▶ 実行ボタンを押してください
🐍 Pyodideで実際のPythonを実行 — 初回は読み込みに3〜5秒

🤖 AIにこう頼んでみましょう

このlessonの概念を知っていれば、AIに具体的に指示できます。漠然とした「直して」ではなく、語彙を持ったリクエスト — それがトークン節約の出発点です。

  • 「この大きなlistのビルドをgenerator(yield)に変えてメモリを節約して」
  • 「itertoolsを使ってもっと効率的にして」

なぜこれがトークンを減らすのか

概念を知らないと、AIの回答を受け取っても「それって何ですか?」と再度聞く必要が出てきます。その「再質問」がトークンを消費します。概念を一度身につければ、会話が一度で終わります

先に読むとよい概念: ラムダ関数
次のおすすめ: デコレーター
ジェネレーター - Python