🐍 Python - Subgenerators
Updated at 2018-06-10 05: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