Python Interview Questions
Python
Web DevelopmentFrontendBackendData ScienceQuestion 26
What is a generator in Python, and how do you use it?
Answer:
A generator in Python is a special type of iterator that allows you to iterate through a sequence of values lazily, meaning it generates values on the fly and only when they are needed. This can be very memory-efficient for large sequences or streams of data. Generators are defined using regular functions but use the yield statement instead of return to produce a series of values.
Creating a Generator
Using yield in a Function
A function becomes a generator function if it contains one or more yield expressions. When called, a generator function returns a generator object that can be iterated over.
Example:
def simple_generator():
    yield 1
    yield 2
    yield 3
# Create a generator object
gen = simple_generator()
# Iterate through the generator
for value in gen:
    print(value)
Output:
1
2
3
In this example:
simple_generatoris a generator function.- Each 
yieldstatement produces a value that can be iterated over. 
Benefits of Generators
- Memory Efficiency: Generators only produce one item at a time, so they use less memory compared to lists.
 - Infinite Sequences: Generators can produce infinite sequences because they don't store the entire sequence in memory.
 - Pipeline Processing: Generators can be used to create data pipelines, allowing for efficient data processing.
 
Example: Generator for Fibonacci Sequence
A generator for an infinite Fibonacci sequence can be defined as follows:
def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b
# Create a generator object
fib_gen = fibonacci()
# Generate the first 10 Fibonacci numbers
for _ in range(10):
    print(next(fib_gen))
Output:
0
1
1
2
3
5
8
13
21
34
Using yield in Loops
You can use yield inside loops to produce a series of values.
Example: Generator for Squares of Numbers
def square_numbers(n):
    for i in range(n):
        yield i ** 2
# Create a generator object
squares = square_numbers(5)
# Iterate through the generator
for square in squares:
    print(square)
Output:
0
1
4
9
16
Generator Expressions
Python also supports generator expressions, which are similar to list comprehensions but produce generators instead of lists. They use a similar syntax but with parentheses instead of square brackets.
Example:
# List comprehension
squares_list = [x ** 2 for x in range(5)]
# Generator expression
squares_gen = (x ** 2 for x in range(5))
# Iterate through the generator
for square in squares_gen:
    print(square)
Output:
0
1
4
9
16
Using Generators for Pipeline Processing
Generators can be composed together to form data processing pipelines. This allows for efficient processing of data in a series of steps.
Example: Chaining Generators
def generate_numbers(n):
    for i in range(n):
        yield i
def filter_even(numbers):
    for number in numbers:
        if number % 2 == 0:
            yield number
def square_numbers(numbers):
    for number in numbers:
        yield number ** 2
# Create a pipeline
numbers = generate_numbers(10)
even_numbers = filter_even(numbers)
squared_numbers = square_numbers(even_numbers)
# Process the pipeline
for square in squared_numbers:
    print(square)
Output:
0
4
16
36
64
Summary
- Generators are special types of iterators defined using functions with 
yieldstatements. - Memory Efficient: Generate values on the fly, using less memory.
 - Infinite Sequences: Can produce infinite sequences without storing the entire sequence in memory.
 - Pipeline Processing: Ideal for creating efficient data processing pipelines.
 
Generators are a powerful feature in Python that allow you to handle large datasets and streams of data efficiently, making them a valuable tool for any Python developer.