python---生成器
·
文字目录
生成器是Python中一种特殊的迭代器,它允许你按需生成值,而不是一次性生成所有值。这在处理大量数据或无限序列时非常有用。
基本概念
什么是生成器?
生成器是一个返回生成器迭代器的函数,它使用yield语句而不是return来返回值。当生成器函数被调用时,它返回一个生成器对象,但不会立即执行函数体。
生成器 vs 普通函数
普通函数:使用return返回值,执行后立即退出
生成器函数:使用yield返回值,每次产生一个值后暂停,下次从暂停处继续
创建生成器
方法1:使用生成器函数
def simple_generator():
yield 1
yield 2
yield 3
# 使用生成器
gen = simple_generator()
print(next(gen)) # 输出: 1
print(next(gen)) # 输出: 2
print(next(gen)) # 输出: 3
# print(next(gen)) # 抛出 StopIteration 异常
方法2:使用生成器表达式
将列表推导式的中括号修改为圆括号。
# 类似于列表推导式,但使用圆括号
squares = (x*x for x in range(5))
print(next(squares)) # 输出: 0
print(next(squares)) # 输出: 1
print(next(squares)) # 输出: 4
# 或者使用循环
for value in squares:
print(value) # 输出: 9, 16
生成器的特点
1. 惰性求值
def count_up_to(max):
count = 1
while count <= max:
yield count
count += 1
counter = count_up_to(5)
for num in counter:
print(num) # 输出: 1, 2, 3, 4, 5
2. 内存效率高
# 普通函数 - 一次性生成所有值
def get_all_squares(n):
result = []
for i in range(n):
result.append(i*i)
return result
# 生成器 - 按需生成值
def generate_squares(n):
for i in range(n):
yield i*i
# 对于大n,生成器更节省内存
3. 无限序列
def infinite_sequence():
num = 0
while True:
yield num
num += 1
inf_gen = infinite_sequence()
for i in range(5):
print(next(inf_gen)) # 输出: 0, 1, 2, 3, 4
高级用法
1. 使用send()方法传递值
def generator_with_send():
value = yield "Ready"
yield f"Received: {value}"
gen = generator_with_send()
print(next(gen)) # 输出: Ready
print(gen.send("Hello")) # 输出: Received: Hello
2. 使用throw()方法抛出异常
def resilient_generator():
try:
yield "Start"
yield "Continue"
except ValueError as e:
yield f"Error handled: {e}"
yield "Recovered"
gen = resilient_generator()
print(next(gen)) # 输出: Start
print(gen.throw(ValueError("Test error"))) # 输出: Error handled: Test error
print(next(gen)) # 输出: Recovered
3. 使用close()方法关闭生成器
def simple_gen():
try:
yield 1
yield 2
yield 3
except GeneratorExit:
print("Generator closed")
gen = simple_gen()
print(next(gen)) # 输出: 1
gen.close() # 输出: Generator closed
实际应用示例
1. 读取大文件
def read_large_file(file_path):
with open(file_path, 'r') as file:
for line in file:
yield line.strip()
# 逐行处理大文件,不一次性加载到内存
for line in read_large_file("large_file.txt"):
process_line(line) # 假设process_line是处理行的函数
2. 生成斐波那契数列
def fibonacci(limit):
a, b = 0, 1
count = 0
while count < limit:
yield a
a, b = b, a + b
count += 1
for num in fibonacci(10):
print(num) # 输出前10个斐波那契数
3. 管道处理数据
def read_data():
for i in range(10):
yield i
def filter_even(numbers):
for num in numbers:
if num % 2 == 0:
yield num
def square(numbers):
for num in numbers:
yield num * num
# 创建处理管道
pipeline = square(filter_even(read_data()))
for result in pipeline:
print(result) # 输出: 0, 4, 16, 36, 64
注意事项
1.生成器只能迭代一次
gen = (x for x in range(3))
list(gen) # [0, 1, 2]
list(gen) # [] - 生成器已耗尽
2.yield from 语法(Python 3.3+)
def chain_generators():
yield from (x for x in range(3))
yield from (x for x in range(3, 6))
for value in chain_generators():
print(value) # 输出: 0, 1, 2, 3, 4, 5
更多推荐




所有评论(0)