Python Generators are a convenient way to create iterators, especially when working with large datasets or sequences. They simplify iteration by using the yield keyword, which allows you to produce a series of values lazily, one at a time, rather than computing all values upfront and storing them in memory.
A generator is a special type of iterator that is defined with a function but does not return all values at once. Instead, it yields values one at a time, which can be iterated over using a loop or similar construct.
• Syntax: Generators are created using a function with at least one yield statement.
• Example:x A generator function is similar to a normal function but uses yield instead of return.
def simple_generator():
yield 1
yield 2
yield 3
gen = simple_generator()
for value in gen:
print(value)
1
2
3
In this example, simple_generator yields values 1, 2, and 3, one at a time, as requested.
• yield: Pauses the function and saves its state. When called again, the function resumes from where it left off.
• return: Ends the function execution and returns a value. Only one return statement is allowed in a function.
def generator_function():
yield 1
yield 2
yield 3
def normal_function():
return [1, 2, 3]
• generator_function uses yield to produce values one by one.
• normal_function creates and returns a complete list all at once.
You can have multiple yield statements in a generator function, allowing it to yield multiple values sequentially.
def count_up_to(max):
count = 1
while count <= max:
yield count
count += 1
for number in count_up_to(5):
print(number)
1
2
3
4
5
Generator expressions provide a concise way to create generators. They are similar to list comprehensions but use parentheses () instead of square brackets [].
generator_expression = (expression for item in iterable if condition)
gen_exp = (x * x for x in range(5))
for value in gen_exp:
print(value)
0
1
4
9
16
1. Easy to Implement: Generators simplify the creation of iterators by handling the state and iteration automatically.
2. Memory Efficient: Generators only produce values one at a time and do not require the entire sequence to be stored in memory. This is particularly useful for large datasets or infinite sequences.
def read_file(file_name):
with open(file_name, 'r') as file:
for line in file:
yield line.strip()
def process_lines(lines):
for line in lines:
yield line.upper()
file_lines = read_file('log.txt')
processed_lines = process_lines(file_lines)
for line in processed_lines:
print(line)
4. Generate Infinite Sequences: Generators can produce an infinite sequence of values, as they only generate values on demand.
def infinite_sequence():
num = 1
while True:
yield num
num += 1
gen = infinite_sequence()
for _ in range(5): # Print the first 5 values
print(next(gen))
1
2
3
4
5