🐍 Python - Subgenerators
Subgenerators
Updated at 2018-06-10 08:58
Generator functions can use subgenerators with yield from keyword. yield from allows a generator to delegate work to another generator.
yield from subgen() makes the subgenerator to take over. Main generator is suspended until the subgenerator terminates.
from typing import Generator
def gen() -> Generator:
yield from 'AB'
yield from range(1, 3)
assert list(gen()) == ['A', 'B', 1, 2]
Subcoroutines are common. yield from syntax is important for coroutine generators as the inner generator will be the target of fetches and send().
from typing import Generator, Optional
def outer(numbers) -> Generator:
while True:
number = yield from inner()
numbers.append(number)
# Generator[yield_type, send_type, return_type]
def inner() -> Generator[None, Optional[int], int]:
number = 0
while True:
received = yield # this is a coroutine
if received is None:
return number
number += received
tallies = []
acc = outer(tallies)
next(acc) # ensure it is ready to accept values
acc.send(1)
acc.send(1)
acc.send(1)
acc.send(None) # finish the first tally
acc.send(2)
acc.send(3)
acc.send(None) # finish the second tally
assert tallies == [3, 5]
Source
- Fluent Python, Luciano Ramalho