Python Tutorial
Python Variable
Python Operators
Python Sequence
Python String
Python Flow Control
Python Functions
Python Class and Object
Python Class Members (properties and methods)
Python Exception Handling
Python Modules
Python File Operations (I/O)
A generator in Python is a special type of iterator that allows you to iterate over a potentially infinite sequence of items without having to store them all in memory. Generators are implemented using functions that contain the yield
keyword, which indicates that the function should return an iterator.
Here's a step-by-step tutorial on how to create and use generators in Python:
yield
keyword. The yield
statement is used to produce a value and pause the function's execution until the next value is requested.def countdown(n): while n > 0: yield n n -= 1
countdown_gen = countdown(5)
for
loop or the next()
function to iterate over the generator. Each time a value is requested, the generator function is resumed from where it was paused, and the next value is produced.for number in countdown_gen: print(number)
Output:
5 4 3 2 1
squares_gen = (x * x for x in range(1, 6))
for
loop or the next()
function to iterate over the generator expression, just like with a generator function.for square in squares_gen: print(square)
Output:
1 4 9 16 25
In this tutorial, you learned how to create and use generators in Python using generator functions and generator expressions. Generators are a powerful and memory-efficient way to work with large or infinite sequences, as they only produce values when they are needed and don't store them in memory. By using generators, you can significantly reduce memory consumption and improve performance in your Python programs.
How to create a generator in Python:
def simple_generator(): yield 1 yield 2 yield 3 my_generator = simple_generator() print(next(my_generator)) # Output: 1 print(next(my_generator)) # Output: 2 print(next(my_generator)) # Output: 3
Generator expressions in Python:
generator_expr = (x for x in range(5)) for value in generator_expr: print(value)
Lazy evaluation and generators in Python:
def lazy_generator(): for i in range(5): yield i my_lazy_generator = lazy_generator() print("Not evaluated yet") for value in my_lazy_generator: print(value)
Iterating with generators in Python:
def count_up_to(limit): current = 1 while current <= limit: yield current current += 1 for number in count_up_to(5): print(number)
Generator functions vs regular functions in Python:
Regular function:
def regular_function(n): return [i for i in range(n)]
Generator function:
def generator_function(n): for i in range(n): yield i
Consuming generators in Python:
def data_generator(): yield "Data 1" yield "Data 2" yield "Data 3" for data in data_generator(): print(data)
Memory efficiency with Python generators:
def large_data_generator(): for i in range(10**6): yield i for value in large_data_generator(): # Process each value without loading all into memory pass
Chaining generators in Python:
def first_generator(): yield 1 yield 2 def second_generator(): yield 3 yield 4 chained_generator = chain(first_generator(), second_generator()) for value in chained_generator: print(value)
Exception handling in Python generators:
def generator_with_exception(): yield 1 raise ValueError("An error occurred") yield 2 my_generator = generator_with_exception() try: for value in my_generator: print(value) except ValueError as e: print(f"Caught an exception: {e}")
Infinite generators in Python:
def infinite_counter(): count = 0 while True: yield count count += 1 my_infinite_generator = infinite_counter() for _ in range(5): print(next(my_infinite_generator))
Generator comprehensions in Python:
generator_expr = (x for x in range(5)) for value in generator_expr: print(value)
Using generators for large data sets in Python:
def process_large_data_set(): data_generator = get_large_data_generator() for data in data_generator: # Process data without loading entire dataset into memory pass