序文
ジェネレーターは Python の中核機能であり、最初にすべての要素を生成するのではなく、要求に応じて新しい要素を生成できるようになります。大規模なデータセットの処理、メモリ効率の高いアルゴリズムの実装、複雑なイテレータ パターンの構築など、さまざまな状況に幅広く応用できます。この記事では、Python ジェネレーターの使用法を理論的および実践的に詳しく説明します。
ジェネレーターの定義と基本操作
yield
ジェネレーターは、関数定義にキーワードを含めることによって作成される特別な種類のイテレーターです。next()
この関数が呼び出されると、関数またはループを使用して新しい要素を取得できるジェネレーター オブジェクトが返されますfor
。
def simple_generator():
yield "Python"
yield "is"
yield "awesome"
# 创建生成器
gen = simple_generator()
# 使用next函数获取元素
print(next(gen)) # 输出: Python
print(next(gen)) # 输出: is
print(next(gen)) # 输出: awesome
# 使用for循环获取元素
for word in simple_generator():
print(word)
# 输出:
# Python
# is
# awesome
ジェネレーターが使い果たされた場合 (つまり、要素がもう生成されなくなった場合)、next()
関数を再度呼び出すとStopIteration
例外が発生します。この例外は手動でキャッチすることも、for
ループによって自動的に処理することもできます。
ジェネレーターの遅延評価とメモリの利点
ジェネレーターの主な利点の 1 つは、遅延評価特性です。つまり、ジェネレーターは必要な場合にのみ要素を計算して生成します。これにより、ジェネレーターは大規模なデータを処理する際のメモリ使用量を大幅に削減できます。リストなどの従来のデータ構造と比較して、ジェネレーターはすべての要素をメモリに保存する必要がなく、反復ごとに新しい要素を動的に計算します。
この機能により、ジェネレーターは、大規模なデータ ストリームの処理、複雑なアルゴリズムの実装、動的データ パイプラインの構築などのシナリオで大きな利点を得ることができます。
# 无限序列生成器
def infinite_sequence():
num = 0
while True:
yield num
num += 1
# 创建生成器
seq = infinite_sequence()
# 输出前10个元素
for i in range(10):
print(next(seq))
# 输出:
# 0
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
この場合、infinite_sequence
終わりのないジェネレーターです。無限の数の要素を生成できますが、ジェネレーターの遅延評価の性質により、メモリは発生しません。
なくなる。
ジェネレータ式
ジェネレーター式は、ジェネレーターを作成するためのより簡潔な方法です。これらはリスト内包表記と似た構文を持ちますが、完全なリストではなくジェネレーター オブジェクトを生成します。これにより、ジェネレータ式で大規模なデータを処理するときに大量のメモリを節約できます。
# 创建一个生成器表达式
gen_expr = (x**2 for x in range(1000000))
# 输出前10个元素
for i in range(10):
print(next(gen_expr))
# 输出:
# 0
# 1
# 4
# 9
# 16
# 25
# 36
# 49
# 64
# 81
この場合、gen_expr
は 10^6 要素の平方を生成するジェネレータ式です。ただし、ジェネレーター式の遅延評価の性質により、これらすべての要素が生成されてメモリに保存されるわけではありません。
ジェネレーターとコルーチン
Python ジェネレーターはコルーチンとしても使用できます。コルーチンは、実行中に一時停止および再開できる特別なタイプの関数であり、単一スレッド内で協調的なマルチタスクの同時実行を可能にします。これにより、ジェネレーターを使用して、同時プログラミング、非同期 IO などの複雑な制御フローを実装できるようになります。
def coroutine_generator():
print("Starting")
while True:
value = (yield)
print(f"Received: {value}")
# 创建生成器
gen = coroutine_generator()
# 启动生成器
next(gen) # 输出: Starting
# 向生成器发送数据
gen.send("Hello") # 输出: Received: Hello
gen.send("Python") # 输出: Received: Python
# 关闭生成器
gen.close()
この場合は、coroutine_generator
コルーチン ジェネレーターです。関数を使用してsend()
データを送信すると、ジェネレーターはデータを受信するとそのデータを出力します。
エピローグ
ジェネレーターは、複雑な問題をより効率的かつ簡潔に処理できるようにする Python の非常に強力なツールです。ジェネレーターの使用に習熟すると、Python プログラミングの自由度が高まり、より強力になります。
もう一つ...
Python の標準ライブラリには、リストをスライスするのと同じように、ジェネレーターをスライスするために使用できるitertools
関数があります。itertools.islice
これは、大規模なデータ ストリームを処理する場合に非常に役立ちます。
import itertools
# 无限序列生成器
def infinite_sequence():
num = 0
while True:
yield num
num += 1
# 创建生成器
seq = infinite_sequence()
# 对生成器进行切片操作
sliced_seq = itertools.islice(seq, 5, 10)
# 输出切片后的元素
for num in sliced_seq:
print(num)
# 输出:
# 5
# 6
#
7
# 8
# 9
この例では、itertools.islice
関数を使用して無限シーケンス ジェネレーターをスライスしseq
、シーケンスの 5 番目から 10 番目の要素 (0 から数えて) を取得します。これにより、大量のメモリを消費することなく、大規模なデータ ストリームを柔軟に処理できるようになります。
Python ジェネレーターの詳細な分析に関するこの記事がお役に立てば幸いです。ジェネレーターについてご質問がある場合、または Python についてさらに詳しく知りたい場合は、以下のメッセージを残して議論してください。
お役に立ちましたら、WeChat の個人公開アカウントにもっと注目してください: [Python の全体像] TeahLead_KrisChang、インターネットおよび人工知能業界で 10 年以上の経験、テクノロジーおよびビジネス チーム管理で 10 年以上の経験、Tongji Softwareエンジニアリング学士、復丹エンジニアリング管理マスター、Aliyun 認定クラウド サービス シニア アーキテクト、数億の収益を誇る AI 製品ビジネスの責任者。