python---生成器
文字目录
- 基本概念
- 什么是生成器?
- 生成器 vs 普通函数
- 创建生成器
- 方法1:使用生成器函数
- 方法2:使用生成器表达式
- 生成器的特点
- 1. 惰性求值
- 2. 内存效率高
- 3. 无限序列
- 高级用法
- 1. 使用send()方法传递值
- 2. 使用throw()方法抛出异常
- 3. 使用close()方法关闭生成器
- 实际应用示例
- 1. 读取大文件
- 2. 生成斐波那契数列
- 3. 管道处理数据
- 注意事项
- 1.生成器只能迭代一次
- 2.yield from 语法(Python 3.3+)
生成器是Python中一种特殊的迭代器,它允许你按需生成值,而不是一次性生成所有值。这在处理大量数据或无限序列时非常有用。
基本概念
什么是生成器?
生成器是一个返回生成器迭代器的函数,它使用yield语句而不是return来返回值。当生成器函数被调用时,它返回一个生成器对象,但不会立即执行函数体。
生成器 vs 普通函数
普通函数:使用return返回值,执行后立即退出
生成器函数:使用yield返回值,每次产生一个值后暂停,下次从暂停处继续
创建生成器
方法1:使用生成器函数
def simple_generator():yield 1yield 2yield 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 = 1while count <= max:yield countcount += 1counter = 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 = 0while True:yield numnum += 1inf_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 1yield 2yield 3except 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, 1count = 0while count < limit:yield aa, b = b, a + bcount += 1for num in fibonacci(10):print(num) # 输出前10个斐波那契数
3. 管道处理数据
def read_data():for i in range(10):yield idef filter_even(numbers):for num in numbers:if num % 2 == 0:yield numdef 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