【Python】12_イテレーターとジェネレーターについての解説

Python Python

イテレータージェネレーターは、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 は、関数をジェネレーターに変え、値を返して関数の実行を一時停止させるキーワードです。

コメント

PAGE TOP
タイトルとURLをコピーしました