イテレータ・ジェネレータを日本一わかりやすく解説!メモリ効率が劇的に向上
イテレータとジェネレータって何?5秒で理解
イテレータ:一つずつ要素を取り出せるオブジェクト
ジェネレータ:必要な時だけ値を作るメモリ効率の良いイテレータ
簡単に言うと、大量のデータを一度にメモリに読み込まず、必要な分だけ処理する仕組みです。
なぜイテレータ・ジェネレータが重要なのか?
メリット
- メモリ効率抜群:100万件のデータでもメモリ使用量は最小限
- 高速処理:必要な分だけ処理するので無駄がない
- 大容量データ対応:メモリに入りきらないデータも処理可能
- 遅延評価:実際に使う時まで計算を遅らせる
イテレータとは?基礎から理解
イテレータの基本概念
イテレータとは、next()関数で次の要素を取得できるオブジェクトです。
# リストをイテレータに変換
my_list = [1, 2, 3]
iterator = iter(my_list)
print(next(iterator)) # 1
print(next(iterator)) # 2
イテレータの作成方法
class CountUp:
def __init__(self, max_num):
self.max_num = max_num
self.num = 0
def __iter__(self):
return self
def __next__(self):
if self.num < self.max_num:
self.num += 1
return self.num
raise StopIteration
# 使用例
counter = CountUp(3)
for num in counter:
print(num) # 1, 2, 3
ジェネレータとは?革命的な機能
ジェネレータ関数の基本
yieldキーワードを使うことで、簡単にジェネレータが作れます。
def count_up(max_num):
num = 0
while num < max_num:
num += 1
yield num
# 使用例
for num in count_up(3):
print(num) # 1, 2, 3
メモリ効率の比較
# 通常のリスト(メモリを大量消費)
def create_list(n):
return [x**2 for x in range(n)]
# ジェネレータ(メモリ効率抜群)
def create_generator(n):
for x in range(n):
yield x**2
# 100万個の要素でも軽々処理
gen = create_generator(1000000) # メモリ使用量:最小限
ジェネレータ式:内包表記の進化版
基本構文
# リスト内包表記
squares_list = [x**2 for x in range(5)]
# ジェネレータ式(括弧を使用)
squares_gen = (x**2 for x in range(5))
実践例:ファイル処理
# 大きなファイルを効率的に処理
def process_large_file(filename):
with open(filename) as f:
return (line.strip().upper() for line in f)
# メモリ効率よく1行ずつ処理
lines = process_large_file('huge_file.txt')
for line in lines:
print(line)
yield文の詳細解説
yield vs return の違い
# return:一度だけ値を返して終了
def normal_function():
return 1
return 2 # 実行されない
# yield:何度でも値を返せる
def generator_function():
yield 1
yield 2
yield 3
gen = generator_function()
print(next(gen)) # 1
print(next(gen)) # 2
yieldの状態保持機能
def fibonacci():
a, b = 0, 1
while True:
yield b
a, b = b, a + b
# フィボナッチ数列を無限に生成
fib = fibonacci()
for _ in range(5):
print(next(fib)) # 1, 1, 2, 3, 5
実践的な使用例
1. CSVファイルの大容量処理
def read_csv_generator(filename):
with open(filename) as f:
for line in f:
yield line.strip().split(',')
# 1GB以上のCSVファイルでもメモリ効率よく処理
for row in read_csv_generator('big_data.csv'):
process_row(row)
2. データベースのページング処理
def fetch_data_pages(page_size=1000):
offset = 0
while True:
data = fetch_from_db(offset, page_size)
if not data:
break
yield from data
offset += page_size
# 大量データを効率的に処理
for record in fetch_data_pages():
process_record(record)
3. 無限シーケンスの生成
def infinite_primes():
yield 2
primes = [2]
candidate = 3
while True:
if all(candidate % p != 0 for p in primes):
primes.append(candidate)
yield candidate
candidate += 2
# 必要な分だけ素数を取得
primes = infinite_primes()
first_ten = [next(primes) for _ in range(10)]
よくある使い方とパターン
yield from:ジェネレータの委譲
def generator1():
yield 1
yield 2
def generator2():
yield 3
yield 4
def combined():
yield from generator1()
yield from generator2()
list(combined()) # [1, 2, 3, 4]
条件付きジェネレータ
def even_squares(n):
for x in range(n):
if x % 2 == 0:
yield x**2
list(even_squares(6)) # [0, 4, 16]
パフォーマンス比較:実際の数値で確認
メモリ使用量の違い
import sys
# リスト:大量のメモリ使用
big_list = [x for x in range(100000)]
print(sys.getsizeof(big_list)) # 約800KB
# ジェネレータ:最小限のメモリ使用
big_gen = (x for x in range(100000))
print(sys.getsizeof(big_gen)) # 約128バイト
処理速度の違い
import time
# リスト作成:時間がかかる
start = time.time()
big_list = [x**2 for x in range(1000000)]
print(f"リスト作成時間: {time.time() - start:.2f}秒")
# ジェネレータ作成:瞬時
start = time.time()
big_gen = (x**2 for x in range(1000000))
print(f"ジェネレータ作成時間: {time.time() - start:.6f}秒")
エラーハンドリングと注意点
StopIteration例外
def simple_gen():
yield 1
yield 2
gen = simple_gen()
print(next(gen)) # 1
print(next(gen)) # 2
# print(next(gen)) # StopIteration例外が発生
ジェネレータの一回限りの性質
gen = (x for x in range(3))
print(list(gen)) # [0, 1, 2]
print(list(gen)) # [] ← もう空!
まとめ:使い分けのポイント
いつ使うべきか?
イテレータを使う場面
- カスタムなデータ構造を作る時
- 複雑な状態管理が必要な時
ジェネレータを使う場面
- 大量データの処理
- メモリ効率を重視する時
- 無限シーケンスが必要な時
- ファイル処理やデータベース処理
パフォーマンス指針
- 小さなデータ(1000件未満):リストでOK
- 中程度のデータ(1万件程度):ジェネレータ推奨
- 大容量データ(10万件以上):ジェネレータ必須
実践演習問題
- 基礎問題:1から10までの偶数を返すジェネレータ関数を作成
- 応用問題:フィボナッチ数列で100未満の数値のみを返すジェネレータ
- 実践問題:テキストファイルから空行を除外して返すジェネレータ
イテレータとジェネレータをマスターすれば、Pythonプログラムのメモリ効率とパフォーマンスが劇的に向上します。まずは小さな例から始めて、徐々に実践的な場面で活用してみましょう!
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座


