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 aStopIterationexception. This signals to the calling code (e.g., aforloop) that the iteration is complete. -
Can I reset a generator?
No, once a generator has been exhausted (i.e., it has raised aStopIterationexception), 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 theyieldkeyword to produce values one at a time, while regular functions use thereturnkeyword 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.