Each stage consumes the previous one lazily. Nothing runs until the consumer (sum()) pulls values.
def read_rows(text):
lines = iter(text.splitlines())
next(lines)
for line in lines:
yield line
def parse(rows):
for row in rows:
region, product, amount = row.split(",")
yield {"region": region, "amount": int(amount)}
def in_region(records, region):
for rec in records:
if rec["region"] == region:
yield rec
east = in_region(parse(read_rows(SALES)), "East")
amounts = (rec["amount"] for rec in east)
print(sum(amounts))
Iterator exhaustion
print(sum(amounts))
print(list(amounts))
def east_amounts(text):
recs = in_region(parse(read_rows(text)), "East")
return (rec["amount"] for rec in recs)
amounts = list(east_amounts(SALES))
print(sum(amounts), max(amounts))
One record travels through every stage before the next line is read. A finished generator cannot rewind.