Python では、イテレータとジェネレータはデータのシーケンスを操作するための強力なツールです。これらを使用すると、シーケンス全体をメモリに保存することなく、データを反復処理できます。このブログでは、イテレータとジェネレータについて、実際の例を交えてわかりやすく説明します。
定義: イテレータは、コレクション (リストやタプルなど) のすべての要素を一度に 1 つずつ走査できるようにする Python のオブジェクトです。これは、__iter__() と __next__() という 2 つのメソッドの実装を含む反復子プロトコルに従います。
イテレータの仕組み:
__iter__(): このメソッドはイテレータ オブジェクト自体を返します。
__next__(): このメソッドはコレクションから次の値を返します。返す項目がもうない場合は、StopIteration 例外が発生します。
カスタム反復子の例:
class MyIterator: def __init__(self, data): self.data = data self.index = 0 def __iter__(self): return self def __next__(self): if self.index < len(self.data): result = self.data[self.index] self.index += 1 return result else: raise StopIteration my_iter = MyIterator([1, 2, 3]) for item in my_iter: print(item)
出力:
1 2 3
説明: この例では、MyIterator は数値のリストを反復処理するカスタム反復子クラスです。 __next__() メソッドはリスト内の次の項目を返し、返す項目がなくなると StopIteration を発生させます。
Python は、リスト、タプル、辞書、セットなどの組み込みコレクション用のデフォルトのイテレータを提供します。 iter 関数を使用してこれらのコレクションからイテレーターを取得し、 next を使用してコレクションを反復処理できます。
my_list = [1, 2, 3] my_iter = iter(my_list) print(next(my_iter)) # Output: 1 print(next(my_iter)) # Output: 2 print(next(my_iter)) # Output: 3 # print(next(my_iter)) # This will raise StopIteration
定義: ジェネレーターは、Python の特別なタイプのイテレーターであり、関数と yield キーワードを使用して定義されます。ジェネレーターを使用すると、すべての値を一度にメモリに保存せずに一連の値を反復処理できるため、リストよりもメモリ効率が高くなります。
ジェネレーターの仕組み:
例:
def my_generator(): yield 1 yield 2 yield 3 gen = my_generator() for item in gen: print(item)
出力:
1 2 3
説明: この例では、my_generator は 3 つの値を 1 つずつ生成するジェネレーター関数です。 yield を呼び出すたびに値が生成され、次の値が要求されるまで関数が一時停止されます。
メモリ効率: ジェネレータはオンザフライで値を生成し、シーケンス全体をメモリに保存しないため、大規模なデータセットやデータ ストリームの操作に最適です。
例:
def large_sequence(): for i in range(1, 1000001): yield i gen = large_sequence() print(next(gen)) # Output: 1 print(next(gen)) # Output: 2
説明: このジェネレーターは、すべてをメモリーに保管せずに 100 万個の数値シーケンスを生成し、そのメモリー効率を実証します。
反復子:
カスタム反復可能オブジェクト: 反復ロジックをさらに制御する必要がある場合。
無限シーケンス: センサーからのデータなど、値の無限シーケンスを生成します。
ジェネレーター:
遅延評価: 大規模なデータセットを一度に 1 項目ずつ処理します。
パイプライン: ストリーミング形式でデータを処理するデータ処理パイプラインを構築します。
定義: ジェネレーター式は、ジェネレーターを作成するための簡潔な方法を提供します。これらはリスト内包表記に似ていますが、角括弧の代わりに括弧を使用します。
例:
gen_exp = (x * x for x in range(5)) for value in gen_exp: print(value)
出力:
0 1 4 9 16
説明: このジェネレーター式は、0 から 4 までの数値の 2 乗を生成するジェネレーターを作成します。
例 1: 大きなファイルの読み取り
def read_large_file(file_path): with open(file_path, 'r') as file: for line in file: yield line for line in read_large_file('large_file.txt'): print(line.strip())
説明: このジェネレーター関数は、大きなファイルを 1 行ずつ読み取り、一度に 1 行ずつ生成します。ファイル全体をメモリにロードしないため、メモリ効率が高くなります。
例 2: フィボナッチ数列
def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b fib = fibonacci() for _ in range(10): print(next(fib))
出力:
0 1 1 2 3 5 8 13 21 34
説明: この生成関数は、フィボナッチ数列の無限シーケンスを生成します。ジェネレーターを使用して、潜在的に無限の値のシーケンスを生成する方法を示します。
* An iterator is an object that allows you to traverse through all the elements of a collection one at a time, implementing the `__iter__()` and `__next__()` methods.
* A generator is a special type of iterator defined using a function and the `yield` keyword, allowing you to generate values on the fly without storing them all in memory.
* Generators are memory-efficient, as they generate values on the fly. They are useful for processing large datasets, building data pipelines, and working with potentially infinite sequences.
* Generator expressions use parentheses and produce values one at a time, whereas list comprehensions use square brackets and generate the entire list in memory.
以上がPython でイテレータとジェネレータを操作する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。