Python 生成器详解
·
什么是生成器?
生成器是Python中一种特殊的迭代器,它不会一次性生成所有值,而是按需生成,这在处理大数据集时非常高效。生成器使用yield关键字而不是return来返回值。
生成器的两种创建方式
- 生成器函数
def count_up_to(max):
count = 1
while count <= max:
yield count # 暂停执行,返回count
count += 1
# 使用生成器
counter = count_up_to(5)
print(next(counter)) # 输出: 1
print(next(counter)) # 输出: 2
print(next(counter)) # 输出: 3
- 生成器表达式
# 类似于列表推导式,但使用圆括号
squares = (x*x for x in range(5))
print(next(squares)) # 输出: 0
print(next(squares)) # 输出: 1
print(list(squares)) # 输出: [4, 9, 16] (注意:继续从上次位置开始)
核心特性与优势
内存效率
# 传统方法:占用大量内存
def get_all_numbers(n):
result = []
for i in range(n):
result.append(i)
return result
# 生成器方法:几乎不占内存
def generate_numbers(n):
for i in range(n):
yield i
# 对比使用
import sys
print(f"列表占用内存: {sys.getsizeof(get_all_numbers(1000))} 字节")
print(f"生成器占用内存: {sys.getsizeof(generate_numbers(1000))} 字节")
无限序列
def infinite_sequence():
num = 0
while True:
yield num
num += 1
# 创建无限计数器
inf_counter = infinite_sequence()
for i in range(5):
print(next(inf_counter)) # 输出: 0, 1, 2, 3, 4
实用示例
文件读取
def read_large_file(file_path):
"""逐行读取大文件,避免内存溢出"""
with open(file_path, 'r', encoding='utf-8') as file:
for line in file:
yield line.strip()
# 使用示例
for line in read_large_file('large_data.txt'):
if 'error' in line:
print(line)
数据处理管道
def number_generator(n):
for i in range(n):
yield i
def square(numbers):
for num in numbers:
yield num ** 2
def filter_even(numbers):
for num in numbers:
if num % 2 == 0:
yield num
# 构建处理管道
pipeline = filter_even(square(number_generator(10)))
print(list(pipeline)) # 输出: [0, 4, 16, 36, 64]
状态保持
def fibonacci_gen():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
fib = fibonacci_gen()
for i in range(10):
print(next(fib), end=' ') # 输出: 0 1 1 2 3 5 8 13 21 34
高级用法
发送数据到生成器
def running_average():
total = 0
count = 0
average = None
while True:
value = yield average
total += value
count += 1
average = total / count
avg_gen = running_average()
next(avg_gen) # 启动生成器
print(avg_gen.send(10)) # 输出: 10.0
print(avg_gen.send(20)) # 输出: 15.0
print(avg_gen.send(30)) # 输出: 20.0
生成器委托
def chain_generators(*iterables):
for iterable in iterables:
yield from iterable # Python 3.3+
# 使用
result = chain_generators(range(3), 'abc', [10, 11])
print(list(result)) # 输出: [0, 1, 2, 'a', 'b', 'c', 10, 11]
使用场景总结
1.大数据处理:逐行读取文件、数据库记录
2.流式数据:网络数据包、实时数据流
3.无限序列:斐波那契数列、素数生成
4.内存敏感应用:移动设备、嵌入式系统
5.数据处理管道:多个处理步骤的串联
更多推荐


所有评论(0)