オブジェクト指向プログラミング(OOP)の中でも、イテレータとジェネレータは、データの反復処理を効率的かつ柔軟に行うための強力な機能です。このセクションでは、Pythonにおけるイテレータとジェネレータの基本概念、使い方、そしてその違いについて、初心者にもわかりやすく解説します。
イテレータは、Pythonでオブジェクトを一つずつ順番に取得するための仕組みです。イテレータは、__iter__()
メソッドと __next__()
メソッドを持つオブジェクトで、for
ループなどの反復処理で利用されます。
イテレータは、以下の2つのメソッドを実装する必要があります。
__iter__()
: イテレータ自身を返します。__next__()
: 次の要素を返します。要素が無くなると StopIteration
例外を発生させます。以下に、カスタムイテレータを実装する例を示します。
class MyIterator:
def __init__(self, limit):
self.limit = limit # イテレータの上限値
self.current = 0 # 現在の値
def __iter__(self):
return self # イテレータ自身を返す
def __next__(self):
if self.current < self.limit:
self.current += 1
return self.current
else:
raise StopIteration # 反復の終了を通知
# MyIteratorクラスのインスタンスを生成
my_iter = MyIterator(5)
# イテレータの使用
for num in my_iter:
print(num)
# 出力:
# 1
# 2
# 3
# 4
# 5
__init__
メソッド:イテレータの上限値と現在の値を初期化します。
__iter__
メソッド:
イテレータ自身を返します。これにより、イテレータがイテラブルオブジェクトとして振る舞います。
__next__
メソッド:
StopIteration
例外を発生させ、反復を終了します。ジェネレータは、イテレータを簡潔に作成するための方法で、特に大きなデータセットや無限シーケンスを扱う際に便利です。ジェネレータは、yield
キーワードを使用して値を一つずつ生成します。
ジェネレータは、通常の関数と同じように定義しますが、値を返す代わりに yield
を使用します。ジェネレータ関数を呼び出すと、ジェネレータオブジェクトが返されます。
以下に、ジェネレータを使用して数値を生成する例を示します。
def my_generator(limit):
current = 0
while current < limit:
current += 1
yield current # 値を生成し、一時停止
# ジェネレータ関数を呼び出してジェネレータオブジェクトを取得
gen = my_generator(5)
# ジェネレータの使用
for num in gen:
print(num)
# 出力:
# 1
# 2
# 3
# 4
# 5
yield
キーワードを使用して値を一つずつ生成します。ジェネレータ関数は、一度に全ての値をメモリに保持する必要がないため、メモリ効率が高いです。
ジェネレータオブジェクト:
for
ループなどの反復処理で使用することで、値を順番に取得できます。特徴 | イテレータ | ジェネレータ |
---|---|---|
実装の複雑さ | 比較的複雑(クラスの定義が必要) | 簡潔(関数内で yield を使用) |
メモリ効率 | 低い場合がある(全ての要素を保持) | 高い(必要な要素だけを生成) |
状態の管理 | 明示的に管理 | Python が自動で管理 |
柔軟性 | 高い(カスタムロジックの実装が可能) | 高い(シンプルなロジックに適) |
大きなファイルを読み込む際に、イテレータとジェネレータを使用して効率的に処理する方法を示します。
class FileIterator:
def __init__(self, filename):
self.file = open(filename, 'r')
def __iter__(self):
return self
def __next__(self):
line = self.file.readline()
if line:
return line.strip()
else:
self.file.close()
raise StopIteration
# FileIteratorクラスのインスタンスを生成
file_iter = FileIterator('sample.txt')
# イテレータを使用してファイルを読み込む
for line in file_iter:
print(line)
def file_generator(filename):
with open(filename, 'r') as file:
for line in file:
yield line.strip()
# ジェネレータ関数を呼び出してジェネレータオブジェクトを取得
gen = file_generator('sample.txt')
# ジェネレータを使用してファイルを読み込む
for line in gen:
print(line)
各行を順番に返し、ファイルの終わりに達すると StopIteration
を発生させます。
ジェネレータの例:
yield
を使用してファイルの各行を逐次生成します。with
文を使用してファイルを開くため、ファイルのクローズ処理も自動的に行われます。__iter__()
と __next__()
メソッドを定義する必要があります。yield
キーワードを使用して簡潔に反復処理を実装でき、メモリ効率が高くなります。