Pythonでは、イテレータはコンテナ(例えばリスト、タプル、辞書、集合、文字列など)内の要素を一度にメモリにロードせずに逐一訪問できるオブジェクトです。イテレータオブジェクトは2つの特殊メソッド、__iter__()
と__next__()
を実装します。__iter__()
メソッドはイテレータオブジェクト自身を返し、__next__()
メソッドはコンテナ内の次の要素を返します。イテレータに返す要素がなくなった場合、__next__()
メソッドはStopIteration
例外を発生させてイテレーションの終了を通知します。
イテレータの利点
- メモリの節約:イテレータは要素を逐一処理できるため、一度にすべての要素をメモリにロードする必要はありません。
- 柔軟性:イテレータは複雑なデータ構造を処理するためにカスタマイズしたり、遅延評価(必要に応じて計算)を実装したりできます。
- 簡潔性:イテレータを使用すると、コードをより簡潔で理解しやすくすることができます。
イテレータの作成
イテレータを作成するには、クラスを定義し、__iter__()
と__next__()
メソッドを実装する必要があります。また、collections.abc.Iterator
を基底クラスとして使用することで、イテレータの実装が正しいかどうかを確認できます。
サンプルコード
以下は、指定範囲内の数字をイテレートするカスタムイテレータクラスを作成する簡単な例です。
from collections.abc import Iterator
class MyRange(Iterator):
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current < self.end:
num = self.current
self.current += 1
return num
else:
raise StopIteration
# カスタムイテレータを使用
my_range = MyRange(1, 5)
for num in my_range:
print(num)
コードの説明
-
Iterator
基底クラスのインポート:collections.abc
モジュールからIterator
基底クラスをインポートし、標準のイテレータインタフェースを実装することを確認します。 -
MyRange
クラスの定義:-
__init__
メソッドで開始値start
、終了値end
、および現在の値current
を初期化します。 -
__iter__
メソッドでイテレータオブジェクト自身(この例ではself
)を返します。 -
__next__
メソッドで現在の値が終了値より小さいかどうかをチェックします。小さい場合、現在の値を返し、現在の値を1増やします。そうでない場合、StopIteration
例外を発生させます。
-
-
カスタムイテレータの使用:
- 指定した開始値と終了値で
MyRange
オブジェクトを作成します。 -
for
ループでMyRange
オブジェクトをイテレートし、各値を印刷します。
- 指定した開始値と終了値で
実行結果
1
2
3
4
この例は、指定範囲内の数字をイテレートする簡単なイテレータを作成する方法を示しています。__iter__()
と__next__()
メソッドを実装することで、より複雑なデータ構造を処理するための独自のイテレータクラスを作成したり、特定のイテレーションロジックを実装したりできます。