📺

空間計算量(メモリ使用量)を抑えるならジェネレータを使おう

2023/06/11に公開

Pythonのジェネレータは、イテレーションが必要な場面でメモリを節約するための強力なツールです。ジェネレータは、一度にすべての要素をメモリに保持するのではなく、要素を一つずつ生成します。これにより、大量のデータを扱う場合でもメモリ使用量を抑えることができます。

以下は、リストとジェネレータの違いを示す簡単な例。

まず、リストを使った場合。

def square_numbers(nums):
    result = []
    for i in nums:
        result.append(i * i)
    return result

my_nums = square_numbers([1, 2, 3, 4, 5])

for num in my_nums:
    print(num)

上記のコードでは、square_numbers関数はリストresultに全ての結果を格納してからそれを返します。これは、入力のリストが非常に大きい場合、それに応じて大量のメモリを消費することを意味します。

次に、ジェネレータを使った場合。

def square_numbers(nums):
    for i in nums:
        yield i * i

my_nums = square_numbers([1, 2, 3, 4, 5])

for num in my_nums:
    print(num)

上記のコードでは、square_numbers関数はジェネレータを返します。yieldキーワードは関数をジェネレータに変換します。ジェネレータはイテレーションごとに一つの値を生成し、その値を使用した後にはメモリから破棄します。そのため、ジェネレータは大量のデータを扱う場合でもメモリ効率が良いです。

ただし、ジェネレータは一度しかイテレートできない点に注意が必要です。全ての要素を再度イテレートする必要がある場合は、ジェネレータを再度生成するか、データをリストや外部ファイルに書き出す等して、格納しておく必要があります。

GitHubで編集を提案

Discussion