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)) # 2
iter()
でイテレータを作成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)) # 1
yield
で値を返し、関数の実行を一時停止next()
されると、停止した場所から再開リスト内包表記に似た構文で、さらに簡潔にジェネレータを作れます。
numbers = (i for i in range(10) if i % 2 == 0)
for n in numbers:
print(n)
項目 | イテレータ(Iterator) | ジェネレータ(Generator) |
---|---|---|
実装方法 | クラスで__iter__ と__next__ を実装 | 関数でyield を使う/ジェネレータ式 |
コード量 | 多い(状態管理が必要) | 少ない(簡潔に書ける) |
メモリ効率 | 実装次第 | 高い(遅延評価・必要な時だけ生成) |
再利用性 | 状態を戻せば再利用可能 | 一度使い切ると再利用不可 |
典型的用途 | 独自の反復処理ロジックが必要な場合 | 大量データや無限データ、メモリ節約したい場合 |
大量データや無限データ、メモリ効率に悩んだら、ぜひジェネレータ・イテレータを活用してみてください。