Python > Advanced Python Concepts > Iterators and Generators > Generator Functions (`yield` keyword)
Generating Fibonacci Sequence with Yield
This snippet demonstrates how to create a generator function using the yield
keyword to produce the Fibonacci sequence. Generator functions are memory-efficient because they generate values on demand, rather than storing the entire sequence in memory.
Basic Generator Function
This code defines a function fibonacci_generator
that takes an integer n
as input, representing the number of Fibonacci numbers to generate. Inside the function, the variables a
and b
are initialized to 0 and 1, respectively. The for
loop iterates n
times. In each iteration, the yield a
statement produces the current value of a
. The values of a
and b
are then updated to calculate the next Fibonacci number. The yield
keyword pauses the function's execution and returns a value. When the next value is requested, the function resumes from where it left off, maintaining its internal state.
def fibonacci_generator(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
# Example usage:
for num in fibonacci_generator(10):
print(num)
Concepts Behind the Snippet
The core concept here is the use of the yield
keyword to create a generator function. A generator function doesn't execute completely at once. Instead, it yields values one at a time when requested. This is crucial for handling large sequences of data without consuming excessive memory. Each time yield
is encountered, the function's state is saved, and the value is returned. When the next value is requested (e.g., by a for
loop or the next()
function), the function resumes execution from the point where it yielded last.
Real-Life Use Case Section
Imagine processing a very large log file. Loading the entire file into memory would be inefficient or even impossible. A generator function can read the file line by line and yield each line. This allows you to process the log file without loading it entirely into memory. Another example is dealing with very large datasets from databases or APIs. Generator can stream process the data, which is specially helpful to train a model for ML, as this data would not fit on memory.
Best Practices
StopIteration
) gracefully.
Interview Tip
Be prepared to explain the difference between a generator function and a regular function. A key difference is that generator functions use the yield
keyword, while regular functions use the return
keyword. Also, be able to discuss the memory efficiency advantages of generators, and the situations where they are most useful.
When to use them
Generator functions are ideal for scenarios where you need to process a large sequence of data iteratively without storing the entire sequence in memory. They are particularly useful for reading large files, processing data streams, and generating infinite sequences. Also they are really helpful to apply lazy evaluation to improve your program.
Memory footprint
The main advantage of generators is their low memory footprint. Instead of storing all the values in memory, they generate each value on demand. This makes them suitable for working with datasets that are too large to fit in memory.
Alternatives
Alternatives to generator functions include:
Pros
yield
keyword simplifies the code for generating sequences.
Cons
Generator expression
Generator expression is similar to list comprehension but creates a generator object. It uses parentheses ()
instead of square brackets []
. In terms of memory usage, it is more efficient than list comprehensions. In this code, we are generating a sequence of squares from 0 to 9.
# Generator expression
squares = (x*x for x in range(10))
# Using the generator
for square in squares:
print(square)
FAQ
-
What happens when a generator reaches the end?
When a generator reaches the end of its sequence (i.e., there are no more values toyield
), it raises aStopIteration
exception. This signals to the calling code (e.g., afor
loop) that the iteration is complete. -
Can I reset a generator?
No, once a generator has been exhausted (i.e., it has raised aStopIteration
exception), you cannot reset it. You must create a new generator object to start the sequence again. -
How are generator functions different from regular functions?
Generator functions use theyield
keyword to produce values one at a time, while regular functions use thereturn
keyword to return a single value. Generator functions maintain their state between calls, allowing them to resume execution from where they left off. Regular functions start from the beginning each time they are called.