この記事では、Pythonにおけるイテレータとジェネレータの違いと使い方について詳しく解説します。具体的なコード例とその解説、さらには応用例も豊富に紹介しています。
目次
イテレータとは
イテレータは、要素を一つずつ取り出せるデータ構造をPythonで実装するためのプロトコルです。リスト、タプル、文字列などは内部でイテレータプロトコルを実装しています。
イテレータの作成方法
イテレータを作成するには、`__iter__()`と`__next__()`メソッドを実装する必要があります。
# イテレータの例
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):
raise StopIteration
value = self.data[self.index]
self.index += 1
return value
ジェネレータとは
ジェネレータはイテレータの一種で、関数内で`yield`キーワードを使用して動的にデータを生成します。ジェネレータはメモリ効率が良く、大量のデータを扱う際に有用です。
ジェネレータの作成方法
`yield`キーワードを用いた関数を作成するだけです。
# ジェネレータの例
def my_generator():
yield 1
yield 2
yield 3
イテレータとジェネレータの違い
メモリ使用量
イテレータは全データをメモリ上に確保する必要がありますが、ジェネレータは必要な時に必要なデータのみを生成します。
簡潔性
ジェネレータは`yield`を使用することで、イテレータよりも短く簡潔にコードを書くことができます。
応用例
ファイルの読み込み
ジェネレータを使用して、大きなファイルを効率よく読み込む方法です。
# 大きなファイルを1行ずつ読むジェネレータ
def read_large_file(file_path):
with open(file_path, "r") as f:
for line in f:
yield line.strip()
フィボナッチ数列
イテレータを使って、フィボナッチ数列を生成する例です。
# フィボナッチ数列を生成するイテレータ
class Fibonacci:
def __init__(self, max_num):
self.max_num = max_num
self.a, self.b = 0, 1
def __iter__(self):
return self
def __next__(self):
if self.a > self.max_num:
raise StopIteration
self.a, self.b = self.b, self.a + self.b
return self.a
リスト内包表記とジェネレータ式
リスト内包表記をジェネレータ式に変更することで、メモリ効率を向上させる例です。
# リスト内包表記
squares = [x*x for x in range(10)]
# ジェネレータ式
squares_gen = (x*x for x in range(10))
まとめ
イテレータとジェネレータはPythonで非常に頻繁に使用される機能です。それぞれの特性を理解し、適切に使用することで、効率的なプログラムを書くことができます。
コメント