The yield
keyword is used in Python to create generator functions. It allows a function to produce a sequence of values lazily, pausing its execution and resuming where it left off when called again. Generators created with yield are more memory-efficient than returning a large list because values are generated one at a time.
Example
def count_up_to(n):
count = 1
while count <= n:
yield count
count += 1
for number in count_up_to(5):
print(number)
Output:
1
2
3
4
5
Syntax
def generator_function():
yield value
- yield: Pauses the function, saves its state, and returns the value to the caller.
- When the function is called again, it resumes execution from where it was paused.
Why Use yield?
- Memory Efficiency: Generators yield values one at a time instead of creating and returning large lists.
- Lazy Evaluation: Values are generated only when needed, which saves computation time.
- Infinite Sequences: Enables the creation of sequences that can be infinitely long without exhausting memory.
- Simpler Code: Simplifies writing iterators by abstracting the logic of maintaining the internal state.
Common Examples
1. Simple Generator Function
def generate_numbers():
yield 1
yield 2
yield 3
for num in generate_numbers():
print(num)
Output:
1
2
3
2. Generator with a Loop
def even_numbers_up_to(n):
for i in range(2, n + 1, 2):
yield i
for even in even_numbers_up_to(10):
print(even)
Output:
2
4
6
8
10
3. Infinite Generator
def infinite_counter():
count = 1
while True:
yield count
count += 1
counter = infinite_counter()
print(next(counter)) # Output: 1
print(next(counter)) # Output: 2
print(next(counter)) # Output: 3
Why? yield allows creating infinite sequences where values are generated on demand.
4. Using Generators with sum()
def squares_up_to(n):
for i in range(1, n + 1):
yield i ** 2
print(sum(squares_up_to(5))) # Output: 55 (1^2 + 2^2 + 3^2 + 4^2 + 5^2)
5. Sending Values to a Generator
Generators can receive values using the send()
method.
def custom_counter():
count = 0
while True:
step = yield count
if step is None:
step = 1
count += step
counter = custom_counter()
print(next(counter)) # Output: 0
print(counter.send(5)) # Output: 5
print(counter.send(2)) # Output: 7