Ever dealt with a huge dataset in Python and run out of memory? Python generators might be the solution. Generators use the yield keyword to produce values one at a time, so you can handle large (even infinite) sequences efficiently. In this beginner-friendly tutorial, we’ll demystify generators – what they are, how they work, and when to use them – so you can write more efficient Python code.
A generator in Python is a special type of function that returns an iterator object. Unlike regular functions that return value(s) and then terminate, generators can pause their execution and resume from where they left off, maintaining their state between calls.
Some key characteristics:
yield
keyword instead of return
Tip💡: Learn about more Python advanced topics like this.
As a simple illustration, let’s compare a regular function with a generator function:
# Regular function
def get_squares(n):
squares = []
for i in range(n):
squares.append(i ** 2)
return squares
# Generator function
def squares_generator(n):
for i in range(n):
yield i ** 2
# Usage comparison
regular_result = get_squares(5) # Creates and stores all values at once
generator_result = squares_generator(5) # Creates values on-demand
regular_result = get_squares(5) # Creates and stores all values at once
generator_result = squares_generator(5) # Creates values on-demand
print(regular_result) # Output: [0, 1, 4, 9, 16]
print(generator_result) # Output: <generator object squares_generator at 0x1078a7780>
Code language: PHP (php)
Python Generators are particularly useful due to their following characteristics:
Here’s a simple example of a generator that yields numbers from 1 to n:
def number_generator(n):
num = 1
while num <= n:
yield num
num += 1
# Using the generator
gen = number_generator(3)
print(next(gen)) # Output: 1
print(next(gen)) # Output: 2
print(next(gen)) # Output: 3
# Let's try one more time for fun
print(next(gen)) # Output: Throws StopIteration error
Code language: PHP (php)
Caution ⚠️: As you might notice, if we try to call the generator function more than the intended limit, it will throw a “StopIteration
” error. So, make sure to catch such exceptions if there’s any unexpected Python method calls for these methods.
In Python, iterators and generators both let you traverse sequences of values one at a time, but they differ in subtle ways:
yield
.The yield
statement is what makes python generators special. When a generator function is called, it returns a generator object without executing the function’s body. The function only executes when next()
it is called on the generator object.
def demonstrate_yield():
print("First point")
yield 1
print("Second point")
yield 2
print("Third point")
yield 3
gen = demonstrate_yield()
print(next(gen))
"""
Output:
First point
1
"""
print(next(gen))
"""
Output:
Second point
2
"""
print(next(gen))
"""
Output:
Third point
3
"""
Code language: PHP (php)
yield
keyword pauses a function’s execution and returns a value, allowing the function to resume where it left off. Each time yield
is called, the generator produces the next value without losing its prior state.
send()
: Send values back to generator throw()
: Raise exceptions inside generator close()
: Stop generator executionHere’s a practical example of using a generator to create an infinite sequence of random numbers:
import random
def random_number_generator(minimum, maximum, seed=None):
"""
Generate an infinite sequence of random numbers between minimum and maximum.
Args:
minimum (int): Lower bound for random numbers
maximum (int): Upper bound for random numbers
seed (int, optional): Seed for random number generation
Yields:
int: Random number between minimum and maximum
"""
if seed is not None:
random.seed(seed)
while True:
yield random.randint(minimum, maximum)
# Usage example
random_gen = random_number_generator(1, 100)
print("Generated random numbers:")
for _ in range(5):
print(next(random_gen))
Code language: PHP (php)
This generator provides several benefits:
A Python generator expression is a compact, lazy-evaluated way to create a generator in a single line—much like a list comprehension, but using parentheses instead of square brackets. Instead of building the entire list in memory, a generator expression yields one item at a time as you iterate over it.
# List comprehension (eager)
squares_list = [x*x for x in range(5)]
# Generator expression (lazy)
squares_gen = (x*x for x in range(5))
print(type(squares_gen))
# → <class 'generator'>
for val in squares_gen:
print(val)
Code language: PHP (php)
Some common scenarios/use cases suitable for Python generators include, but are not limited to:
def read_file_lines(filename):
with open(filename, 'r') as file:
for line in file:
yield line.strip()
# Usage
for line in read_file_lines('large_file.txt'):
process_line(line)
Code language: PHP (php)
def fibonacci_generator():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
# Get first 10 Fibonacci numbers
fib = fibonacci_generator()
for _ in range(10):
print(next(fib))
Code language: PHP (php)
# Memory inefficient
def get_all_numbers(n):
return [i for i in range(n)]
# Memory efficient
def get_numbers_generator(n):
for i in range(n):
yield i
Code language: PHP (php)
Python generators are a powerful tool for creating memory-efficient iterators. They’re particularly useful when working with large datasets or infinite sequences. By using the yield
keyword and understanding generator expressions, you can write more efficient and cleaner code.
Remember that generators are lazy and compute values only when needed, making them perfect for scenarios where memory efficiency is crucial. Start incorporating generators into your Python projects, and you’ll soon appreciate their elegance and utility.
Also, refer to the official documentation to learn more.
Is there anything I missed, or do you have any specific questions about Python generators? Feel free to comment below. Happy Python programming 🐍!
Unlock the full potential of service workers with advanced features like push notifications, background sync, and performance optimization techniques that transform your web app into…
Learn how to integrate service workers in React, Next.js, Vue, and Angular with practical code examples and production-ready implementations for modern web applications.
Master the essential service worker caching strategies that transform web performance. Learn Cache-First, Network-First, and Stale-While-Revalidate patterns with practical examples that'll make your apps blazingly…
This website uses cookies.