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出力:
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 StopIteration2. ジェネレーターとは何ですか?
定義: ジェネレーターは 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.
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3