PYTHON Reference Guide
Revision Time: 3 mins

Generators Reference

Generator functions and expressions — yielding values lazily without building full sequences.

yield
Return: generator

Pause a function and return a value; resume from where it left off on next().

Used In: Streaming data rows, reading file chunks, infinite sequences.

Syntax signature:def gen_func(): yield value
Code snippet:
python
def countdown(n):
    while n > 0:
        yield n
        n -= 1

for x in countdown(3):
    print(x)
Expected Output:3 2 1

Time Complexity: O(1) per yield

Related Methods: next(), iter()

Comparison:

Generator function vs regular function: a generator suspends and resumes; a regular function runs to completion each call.

Remember: Each call to next() resumes execution right after the yield statement — local state is preserved.
Generator Expression
Return: generator

Compact one-line lazy generator — like list comprehension but memory-efficient.

Used In: Large aggregations, streaming data transformations.

Syntax signature:(expr for item in iterable if condition)
Code snippet:
python
import sys
lst = [x**2 for x in range(100000)]
gen = (x**2 for x in range(100000))
print(sys.getsizeof(lst))
print(sys.getsizeof(gen))
Expected Output:824456 104

Time Complexity: O(1) memory, O(N) computation

Related Methods: yield

Comparison:

[...] creates a list in memory; (...) creates a lazy generator.

Remember: Use generator expressions inside sum(), max(), any() — the () wrapping is optional when it's the only argument.
yield from
Return: generator

Delegate to a sub-generator or iterable, yielding all its values.

Used In: Recursively flattening nested structures, delegating to sub-pipelines.

Syntax signature:yield from iterable
Code snippet:
python
def flatten(nested):
    for sub in nested:
        yield from sub

batches = [[1, 2], [3, 4], [5]]
print(list(flatten(batches)))
Expected Output:[1, 2, 3, 4, 5]

Time Complexity: O(N) total iteration

Related Methods: yield

Remember: yield from is cleaner than a nested for loop with yield — and it propagates send() and throw() calls correctly.
send()
Return: T (next yielded value)

Resume a generator and pass a value back into it at the yield point.

Used In: Coroutines, stateful streaming aggregation, pipeline coordination.

Syntax signature:gen.send(value)
Code snippet:
python
def accumulator():
    total = 0
    while True:
        val = yield total
        if val is None:
            break
        total += val

acc = accumulator()
next(acc)
print(acc.send(10))
print(acc.send(25))
print(acc.send(5))
Expected Output:10 35 40

Time Complexity: O(1)

Common Mistakes: Calling send() before priming with next() raises TypeError.

Remember: You must call next() (or send(None)) once to advance to the first yield before sending values.
Memory Efficiency
Return: generator

Generators never build the full sequence — they yield one value at a time.

Used In: Processing large CSV/JSON files, streaming Kafka messages.

Syntax signature:gen = (transform(row) for row in large_file)
Code snippet:
python
import sys
lst = [x for x in range(100000)]
gen = (x for x in range(100000))
print(sys.getsizeof(lst))
print(sys.getsizeof(gen))
Expected Output:824456 104

Time Complexity: O(1) memory

Related Methods: yield, itertools

Remember: A generator object is always tiny (~120 bytes) regardless of how many values it will produce.