A generator is a special type of function that:
✔ Produces values one at a time
✔ Does NOT store everything in memory
✔ Uses the yield keyword
Generators = Lazy Iteration
Normal function:
return → Ends functionGenerator function:
yield → Pauses function✔ Remembers state
✔ Resumes later
✔ Memory efficient
✔ Faster for large data
✔ Lazy evaluation
✔ Infinite sequences
✔ Streaming data
✔ Used heavily in real systems
def get_numbers():
return [1, 2, 3]✔ Creates FULL list in memory
def get_numbers():
yield 1
yield 2
yield 3✔ Produces values one-by-one
gen = get_numbers()
print(gen)Output:
<generator object get_numbers at 0x...>
✔ It’s NOT executed yet
print(next(gen))
print(next(gen))
print(next(gen))Output:
1
2
3
✔ Each next() resumes execution.
yield → Pause → Save State → Resume
Python keeps:
✔ Local variables
✔ Execution position
✔ Internal context
def count_up_to(n):
i = 1
while i <= n:
yield i
i += 1gen = count_up_to(3)
for num in gen:
print(num)Output:
1
2
3
✔ Clean & elegant.
numbers = [x for x in range(1000000)]✔ Stores EVERYTHING
numbers = (x for x in range(1000000))✔ Produces on demand
gen = (x * 2 for x in range(5))
for num in gen:
print(num)Output:
0
2
4
6
8
✔ Like list comprehension but lazy.
Reading HUGE file
def read_large_file():
with open("huge.txt") as f:
for line in f:
yield line✔ Processes line-by-line
✔ No memory explosion
def infinite_counter():
i = 1
while True:
yield i
i += 1✔ Runs forever
gen = get_numbers()
list(gen)
list(gen) # EMPTY ✔ Generators run ONLY once.
gen[0] # ERROR ✔ No random access.
Generator does NOTHING until:
✔ next()
✔ Loop
✔ list()
return → Ends
yield → PausesBig difference
Generators hide flow.
✔ Harder to trace logic.
Generators enable:
✔ Lazy pipelines
✔ Streaming systems
✔ Data processing chains
✔ Memory-safe iteration
✔ Functional composition
def generator1():
yield 1
yield 2
def generator2():
yield from generator1()
yield 3for x in generator2():
print(x)Output:
1
2
3
✔ Delegates iteration
Large datasets
File processing
Infinite sequences
Streaming APIs
Pipelines
Memory-critical apps
Tiny lists.
✔ Use for large data
✔ Avoid unnecessary conversion
✔ Remember exhaustion
✔ Keep logic simple
✔ Prefer generator expressions
✔ Generators = Lazy evaluation
✔ Use yield keyword
✔ Memory efficient
✔ State preserved between yields
✔ Can create infinite sequences
✔ Generator expressions available
✔ Exhaustible
- Create simple generator
- Use next() manually
- Build generator with loop
- Create generator expression
- Create infinite generator
- Demonstrate exhaustion
- Use yield from
- Simulate file reader