「イテレータ (iterator)」とは、プログラミングにおいて、データの集合(リスト、タプル、辞書、集合など)の要素に順番にアクセスするための仕組みを提供するオブジェクトのことです。
イテレータを使うと、データの集合全体を一度にメモリに読み込む必要がないため、大量のデータを扱う場合にメモリ効率が良いというメリットがあります。
また、要素を一つずつ順番に取り出すという共通のインターフェースを提供するため、様々なデータ構造に対して統一的な方法でアクセスできます。
イテレータの基本的な動き
イテレータは、主に以下の2つのメソッドを持っています。
__iter__()
: イテレータ自身を返します。これは、イテレータがfor
ループなどで使えるようにするために必要です。__next__()
: 次の要素を返します。- 呼び出すたびに、データの集合の次の要素を返します。
- すべての要素が取り出された後、
__next__()
を呼び出すとStopIteration
という例外が発生し、要素の終端を示します。
イテラブル (iterable)
イテレータとよく似た言葉に「イテラブル (iterable)」があります。イテラブルとは、要素を一つずつ返すことができるオブジェクトのことです。リスト、タプル、文字列、辞書、集合などがイテラブルの例です。
イテラブルなオブジェクトは、iter()
関数に渡すことでイテレータを取得できます。
イテレータの例
リストをイテラブルとして、そのイテレータを使って要素にアクセスする例を見てみましょう。
Python
my_list = [1, 2, 3]
# iter() 関数でイテラブルからイテレータを取得
my_iterator = iter(my_list)
# __next__() メソッドで要素を順番に取り出す
print(next(my_iterator)) # 出力: 1
print(next(my_iterator)) # 出力: 2
print(next(my_iterator)) # 出力: 3
# すべての要素を取り出した後に next() を呼び出すと StopIteration エラーが発生
try:
print(next(my_iterator))
except StopIteration:
print("要素はもうありません")
for ループとイテレータ
Pythonの for
ループは、内部的にイテレータの仕組みを利用しています。for
ループがイテラブルなオブジェクトに対して実行されると、以下の処理が行われます。
- イテラブルからイテレータを取得します (
iter()
関数)。 - ループの各イテレーションで、イテレータの
__next__()
メソッドを呼び出して次の要素を取得します。 StopIteration
例外が発生すると、ループを終了します。
Python
my_list = [10, 20, 30]
for item in my_list:
print(item)
この for
ループは、裏側で以下のような処理を行っています。
Python
my_list = [10, 20, 30]
my_iterator = iter(my_list)
while True:
try:
item = next(my_iterator)
print(item)
except StopIteration:
break
glob.iglob() とイテレータ
glob.iglob()
関数は、パターンにマッチするファイルパス名をリストとしてではなく、イテレータとして返します。これにより、大量のファイルパスを一度にメモリに読み込む必要がなくなり、メモリ使用量を大幅に削減できます。
glob.iglob()
を使うことで、見つかったファイルパスを一つずつ順番に処理できるため、非常に効率的です。
globについてはこちらで解説しています。
まとめ
イテレータは、データの集合の要素に順番にアクセスするためのオブジェクトです。
__iter__()
メソッドと __next__()
メソッドを持ち、__next__()
メソッドが StopIteration
例外を発生させることで要素の終端を示します。
for
ループは内部的にイテレータを利用しており、glob.iglob()
のようにイテレータを返す関数を使うことで、メモリ効率の良いデータ処理が可能になります。
コメント