An iterable can supply an iterator. An iterator remembers its position, and next advances it. Once exhausted, a normal iterator stays exhausted. A generator function uses yield to produce values one at a time while retaining its local state between requests. That makes it useful for batches and running totals without building every intermediate value first. These exercises materialize the final result as a list because the workspace compares JSON-compatible values, but the helpers inside your function can remain lazy. Watch the final partial batch and the stop marker. Both are easy to lose when you translate a loop into a generator. No task requires a background thread or external stream.