Pythonで大量データや効率的な処理が求められる場面で欠かせないのが「イテレータ」と「ジェネレータ」です。本記事では、両者の仕組み・違い・具体的な使い方・活用例まで、初心者にも分かりやすく解説します。
「for文の裏側で何が起きているのか」「メモリ効率を高めたい」「無限データを扱いたい」といった疑問や課題を解決できる内容です。
イテレータは、リストやタプルなどのコレクションから要素を「1つずつ順番に取り出す」ためのオブジェクトです。
Pythonのイテレータは、__iter__()と__next__()という2つのメソッドを持ち、iter()で作成し、next()で次の要素を取得します。
numbers = [1, 2, 3, 4, 5]
iterator = iter(numbers)
print(next(iterator)) # 1
print(next(iterator)) # 2iter()でイテレータを作成next()で順次要素を取得StopIteration例外が発生独自のイテレータは、__iter__()と__next__()を実装したクラスで作成できます。
class MyIterator:
def __init__(self, max_value):
self.max_value = max_value
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current < self.max_value:
self.current += 1
return self.current - 1
else:
raise StopIterationジェネレータは、「必要な時にだけ次の値を生成する」特別なイテレータです。
最大の特徴は、yieldキーワードを使うことで、複雑なイテレータを簡潔に実装できる点にあります。
def count_up():
x = 0
while True:
yield x
x += 1
gen = count_up()
print(next(gen)) # 0
print(next(gen)) # 1yieldで値を返し、関数の実行を一時停止next()されると、停止した場所から再開リスト内包表記に似た構文で、さらに簡潔にジェネレータを作れます。
numbers = (i for i in range(10) if i % 2 == 0)
for n in numbers:
print(n)| 項目 | イテレータ(Iterator) | ジェネレータ(Generator) |
|---|---|---|
| 実装方法 | クラスで__iter__と__next__を実装 | 関数でyieldを使う/ジェネレータ式 |
| コード量 | 多い(状態管理が必要) | 少ない(簡潔に書ける) |
| メモリ効率 | 実装次第 | 高い(遅延評価・必要な時だけ生成) |
| 再利用性 | 状態を戻せば再利用可能 | 一度使い切ると再利用不可 |
| 典型的用途 | 独自の反復処理ロジックが必要な場合 | 大量データや無限データ、メモリ節約したい場合 |
大量データや無限データ、メモリ効率に悩んだら、ぜひジェネレータ・イテレータを活用してみてください。