0Pricing
Python Academy · レッスン

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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. イテレータプロトコル
  2. ジェネレータ関数
  3. ジェネレータ式
  4. yield fromと委譲
← Python Academyに戻る