イテレーターとジェネレーターは、Pythonで効率的にデータを反復処理するための強力な仕組みです。これらは、大量のデータや無限のシーケンスを扱う際に便利です。
この記事では、イテレーターとジェネレーターの基本的な動作や関連する関数・キーワード(iter()、next()、yield)について解説します。
イテレーターとジェネレーターを使うことで、効率的にデータを反復処理でき、メモリ消費を最小限に抑えることが可能です。
1. イテレーターとは?
**イテレーター(Iterator)**は、要素を1つずつ順に取り出すことができるオブジェクトです。イテレーターを使うことで、リストやタプルのようなデータ構造の要素を繰り返し処理することができます。
イテレーターの特徴
-
iter() 関数を使ってイテラブルオブジェクトからイテレーターを取得します。
-
next() 関数を使って次の要素を取得します。
-
最後の要素に達すると**StopIteration** 例外が発生し、反復が終了します。
例: リストをイテレーターで処理する
my_list = [1, 2, 3, 4]
# イテレーターを作成
my_iter = iter(my_list)
# next() を使って要素を1つずつ取得
print(next(my_iter)) # 1
print(next(my_iter)) # 2
print(next(my_iter)) # 3
print(next(my_iter)) # 4
# リストの最後の要素に到達すると StopIteration が発生
# print(next(my_iter)) # StopIteration エラー
この例では、iter() 関数でリストのイテレーターを取得し、next() 関数で順に要素を取得しています。
リストの要素がなくなると、StopIteration 例外が発生します。
2. iter() 関数
iter() は、イテラブルオブジェクト(リスト、タプル、文字列など)からイテレーターを作成する関数です。イテラブルオブジェクトとは、繰り返し処理が可能なオブジェクトを指します。iter() を使って、これらのオブジェクトをイテレーターに変換できます。
例: iter() の使用
my_list = [10, 20, 30]
# リストからイテレーターを取得
my_iter = iter(my_list)
print(my_iter) # <list_iterator object at 0x...>
3. next() 関数
next() は、イテレーターから次の要素を取得するための関数です。次の要素がない場合には、StopIteration 例外が発生します。for ループはこの next() 関数を内部で使用して要素を1つずつ取り出しています。
例: next() の使用
my_list = [10, 20, 30]
# イテレーターを取得
my_iter = iter(my_list)
# next() で次の要素を取得
print(next(my_iter)) # 10
print(next(my_iter)) # 20
print(next(my_iter)) # 30
# 次の要素がない場合、StopIteration エラーが発生
# print(next(my_iter)) # StopIteration エラー
4. ジェネレーターとは?
ジェネレーター(Generator)は、Pythonでイテレーターを簡単に作成するための特殊な関数です。通常の関数とは異なり、yield キーワードを使って値を返します。yield を使うことで、関数の実行が一時停止し、次回再開したときにその時点から処理を続けることができます。
ジェネレーターの特徴
-
yield を使って値を返します(return の代わりに)。
-
一度に全ての値をメモリにロードするのではなく、必要なときに次の値を計算します。
-
メモリ効率が良いため、大きなデータや無限のシーケンスに適しています。
例: ジェネレーター関数
def count_up_to(limit):
num = 0
while num < limit:
yield num # 値を返し、一時停止
num += 1
# ジェネレーターを作成
counter = count_up_to(3)
# next() でジェネレーターから値を取得
print(next(counter)) # 0
print(next(counter)) # 1
print(next(counter)) # 2
# これ以上の値はないので StopIteration が発生
# print(next(counter)) # StopIteration エラー
この例では、yield を使って 0 から limit までの数を順に返すジェネレーター関数を定義しています。
next() を呼び出すたびに、yield によって値が返され、ジェネレーターが次のステップに進みます。
5. yield キーワード
yield は、関数をジェネレーターに変えるためのキーワードです。yield を使うと、関数は値を返して一時停止し、次に呼び出されたときにその位置から処理を再開します。これは、メモリ効率が良く、大きなデータや無限に続くデータを処理するのに適しています。
例: ジェネレーターの使用
def fibonacci():
a, b = 0, 1
while True:
yield a # フィボナッチ数列の次の値を返す
a, b = b, a + b
# ジェネレーターを作成
fib_gen = fibonacci()
# フィボナッチ数列の最初の5つの値を取得
for _ in range(5):
print(next(fib_gen))
結果
0
1
1
2
3
この例では、無限にフィボナッチ数列を生成するジェネレーターを定義しています。
yield によって数列の次の値が返され、next() が呼び出されるたびに次のフィボナッチ数が計算されます。
まとめ
-
イテレーターは、iter() で作成され、next() で次の要素を順に取り出すことができるオブジェクトです。リストやタプルなどのイテラブルなデータを反復処理するのに使います。
-
iter() 関数は、イテラブルオブジェクトからイテレーターを作成します。
-
next() 関数は、イテレーターの次の要素を取得します。要素がなくなると StopIteration 例外が発生します。
-
ジェネレーターは、yield キーワードを使って値を一時停止しながら返すイテレーターの一種です。
必要な時に値を計算するため、メモリ効率が良く、大規模データや無限シーケンスの処理に適しています。 -
yield は、関数をジェネレーターに変え、値を返して関数の実行を一時停止させるキーワードです。
コメント