def countdown(n: int):
while n > 0:
yield n
n -= 1for tick in countdown(3):
print(tick)
# Generators are lazy — values produced one at a time
nums = countdown(1_000_000)
print(next(nums))
output
3
2
1
1000000
Note Generators produce values lazily, consuming almost no memory regardless of size. They are single-use: once exhausted, they cannot be restarted.
def flatten(nested):
for item in nested:
if isinstance(item, list):
yieldfrom flatten(item)
else:
yield item
data = [1, [2, [3, 4]], [5, 6]]
print(list(flatten(data)))
output
[1, 2, 3, 4, 5, 6]
Note yield from delegates to a sub-generator and passes values through. It handles send() and throw() transparently, unlike a manual for-loop with yield.