yield fromと委譲
ジェネレータを組み合わせます
「yield fromと委譲」はCoddyKit上の無料Python Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPython Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Python Academyコースには全4レッスンが含まれています。
yield fromが解決する問題
あるジェネレーターが別のイテラブルのすべての値を生成したい場合、手動でループを記述できます。yield fromを使えば、同じことを1行で実現できます。
def manual():
for x in [1, 2, 3]:
yield x
print(list(manual()))yield fromの紹介
yield from iterableはそのイテラブルに処理を委譲し、含まれる値を順番に1つずつ生成します。値を転送するループよりも短く、読みやすくなります。
def delegate():
yield from [1, 2, 3]
print(list(delegate()))複数のソースの結合
複数のyield from文を連結して、シーケンスを遅延評価で結合できます。
def chained():
yield from 'ab'
yield from [1, 2]
yield from range(2)
print(list(chained()))別のジェネレーターへの委譲
委譲先のイテラブル自体をジェネレーターにすることもできるため、複数のジェネレーターを組み合わせて、より大きなジェネレーターを構築できます。
def evens(n):
for i in range(n):
if i % 2 == 0:
yield i
def report(n):
print('evens:')
yield from evens(n)
print(list(report(6)))ネストしたリストの平坦化
yield fromの典型的な用途は、再帰的な平坦化です。サブリストに対する処理を自分自身に委譲するジェネレーターを作成します。
def flatten(items):
for item in items:
if isinstance(item, list):
yield from flatten(item)
else:
yield item
print(list(flatten([1, [2, [3, 4]], 5])))yield fromとループの違い
以下の2つのバージョンは同じ出力を生成します。yield fromは読みやすく、値の送信や戻り値などの高度な機能も転送できるため、こちらが推奨されます。
def with_loop(src):
for x in src:
yield x
def with_yield_from(src):
yield from src
print(list(with_loop(range(3))))
print(list(with_yield_from(range(3))))サブジェネレーターの戻り値を取得する
委譲先のジェネレーターが値をreturnすると、yield fromはその値に評価されます。これにより、サブジェネレーターから結果を報告できます。
def counter(n):
count = 0
for i in range(n):
yield i
count += 1
return count
def driver():
total = yield from counter(3)
print('subgen yielded', total, 'items')
list(driver())パイプラインを構築する
委譲を使うと、パイプラインを名前付きの段階に分割し、それらを組み合わせることが簡単になります。
def source():
yield from range(5)
def only_odd(src):
for x in src:
if x % 2 == 1:
yield x
def pipeline():
yield from only_odd(source())
print(list(pipeline()))任意のイテラブルに委譲する
yield fromはジェネレーターだけでなく、リスト、タプル、集合、文字列、辞書のキーなど、任意のイテラブルで使用できます。
def mixed():
yield from {1, 2, 3}
yield from ('a', 'b')
result = list(mixed())
print(sorted(str(x) for x in result))ジェネレーターを順番に結合する
複数のソースを順番にたどるジェネレーターを構築できます。これはストリームの結合に便利です。
def concat(*iterables):
for it in iterables:
yield from it
print(list(concat([1, 2], [3], [4, 5])))読みやすさを高める
深くネストしたデータやツリー構造のデータでは、yield fromによって再帰ジェネレーターを短くし、意図を明確に表現できます。
def walk(tree):
yield tree['name']
for child in tree.get('children', []):
yield from walk(child)
tree = {'name': 'root', 'children': [
{'name': 'a'},
{'name': 'b', 'children': [{'name': 'c'}]}
]}
print(list(walk(tree)))理解度チェック
yield fromの理解度を確認しましょう。
まとめ
yield fromと委譲について学びました。
- 内部のイテラブルからすべての値を転送します。
- ジェネレーターを組み合わせたり、再帰的な平坦化を実現したりできます。
- サブジェネレーターの戻り値を取得できます。
- 手動で値を転送するループよりも明確です。
次のコースでは、スレッドとマルチプロセスによる並行処理を学びます。
よくある質問
「yield fromと委譲」レッスンは無料ですか?
はい。「yield fromと委譲」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Python Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Python Academyコースには全4レッスンが含まれています。
「yield fromと委譲」で何を学びますか?
ジェネレータを組み合わせます ブラウザで直接実行するハンズオンコードでPython Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Python Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのPython Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「yield fromと委譲」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このPython Academyレッスンでコードを書いて実行できますか?
はい。すべてのPython Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- イテレータプロトコル
- ジェネレータ関数
- ジェネレータ式
- yield fromと委譲