-
efine a Function with
yieldStatements:
Generators are defined like regular functions but useyieldto return values. Eachyieldpauses the function, saving its state for the next call.def count_up_to(max): count = 0 while count <= max: yield count count += 1
-
Create a Generator Object:
Call the function to get a generator object. The function doesn’t execute immediately; it starts on the firstnext()call.gen = count_up_to(3) # Generator object created
-
Iterate Over the Generator:
Usenext()to get values one at a time or loop withfor:print(next(gen)) # Output: 0 print(next(gen)) # Output: 1 for num in gen: # Continues from 2 print(num) # Output: 2, 3
Examples:
-
Even Numbers Generator:
def even_numbers(max_num): current = 0 while current <= max_num: yield current current += 2 for num in even_numbers(6): print(num) # Output: 0, 2, 4, 6
-
Reverse List Generator:
def reverse_generator(lst): index = len(lst) - 1 while index >= 0: yield lst[index] index -= 1 for item in reverse_generator([1, 2, 3]): print(item) # Output: 3, 2, 1
-
Generator Expression:
Use parentheses for concise generators:squares = (x**2 for x in range(5)) print(list(squares)) # Output: [0, 1, 4, 9, 16]
Key Points:
-
Memory Efficiency: Generators produce items on-the-fly, ideal for large datasets.
-
State Retention: Resumes execution from the last
yield. -
Use Cases: Large file processing, infinite sequences (e.g., Fibonacci), and data pipelines.
Advanced Use:
-
.send(value): Send values back into a generator. -
yield from: Delegate to another generator.
Example of an Infinite Fibonacci Generator:
def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b fib = fibonacci() for _ in range(5): print(next(fib)) # Output: 0, 1, 1, 2, 3
Generators streamline handling of sequences with minimal memory usage and efficient iteration.












