【Python】ジェネレータを利用してイテレータを取得する

【Python】ジェネレータを利用してイテレータを取得する

Pythonのジェネレータを利用してイテレータを取得する

Pythonのジェネレータを利用してイテレータを取得する

ジェネレータとは?

ジェネレータ(generator)は、Pythonのイテレータ(iterator)を簡単に作成できる特殊な関数です。通常の関数とは異なり、return の代わりに yield を使います。

ジェネレータを利用すると、要素を逐次的に生成できるため、メモリ効率が向上し、大量のデータを扱う際に有用です。

基本的な使い方

まずは基本的なジェネレータの定義と使用方法を見てみましょう。

def simple_generator():
    yield 1
    yield 2
    yield 3

gen = simple_generator()
print(next(gen))  # 1
print(next(gen))  # 2
print(next(gen))  # 3
# print(next(gen))  # StopIteration エラー

yield を使うことで、関数が途中で停止し、次に next() を呼び出すと、停止した位置から再開します。

通常の関数との違い

通常の関数とジェネレータの違いを比較します。

通常の関数

def normal_function():
    return [1, 2, 3]

print(normal_function())  # [1, 2, 3]

ジェネレータ

def generator_function():
    yield 1
    yield 2
    yield 3

gen = generator_function()
print(list(gen))  # [1, 2, 3]

通常の関数は全てのデータを一度に返しますが、ジェネレータは1つずつ値を返します。

実用的なジェネレータの例

ファイルの行を1行ずつ読む

def read_large_file(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        for line in file:
            yield line.strip()

for line in read_large_file("large_text.txt"):
    print(line)

無限に値を生成する

def infinite_counter():
    num = 0
    while True:
        yield num
        num += 1

counter = infinite_counter()
print(next(counter))  # 0
print(next(counter))  # 1
print(next(counter))  # 2

パフォーマンスの利点

  • ジェネレータは一度に1つの値しかメモリに保持しないため、メモリ使用量が削減される。
  • 大きなリストを作成せずにデータを逐次処理できるため、処理速度が向上する。

応用的なジェネレータの使い方

ジェネレータでフィルタリング

def even_numbers(n):
    for num in range(n):
        if num % 2 == 0:
            yield num

print(list(even_numbers(10)))  # [0, 2, 4, 6, 8]

ジェネレータを使ったパイプライン処理

def numbers():
    for i in range(10):
        yield i

def square(numbers):
    for num in numbers:
        yield num ** 2

def even_filter(numbers):
    for num in numbers:
        if num % 2 == 0:
            yield num

pipeline = even_filter(square(numbers()))
print(list(pipeline))  # [0, 4, 16, 36, 64]

ジェネレータ式

リスト内包表記に似た形でジェネレータを作成できます。

gen_exp = (x**2 for x in range(10))
print(next(gen_exp))  # 0
print(next(gen_exp))  # 1

リスト内包表記 [x**2 for x in range(10)] と違い、ジェネレータ式は必要な時に値を生成します。

まとめ

  • ジェネレータは yield を使用し、イテレータを簡単に作れる。
  • メモリ効率が良く、大量のデータ処理に適している。
  • ファイル処理や無限ループなど、実用的な用途が多い。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です