本文目录导读:

Python脚本生成器通过惰性求值(Lazy Evaluation)来节省内存,与列表一次性加载所有数据不同,生成器只在需要时才生成下一个元素,因此占用的是常数量级的内存。
核心原理
对比示例
# 列表方式 - 一次性加载100万数据到内存 my_list = [x * 2 for x in range(1_000_000)] # 约8MB内存 # 生成器方式 - 按需生成,仅占用几十字节 my_generator = (x * 2 for x in range(1_000_000)) # 约56字节
主要节省内存的场景
处理大文件时
# 错误方式:一次读入所有行
with open('large_file.txt') as f:
lines = f.readlines() # 全部加载到内存
# 正确方式:逐行读取(生成器行为)
with open('large_file.txt') as f:
for line in f: # f本身是生成器
process(line)
大数据流处理
# 传统方式
def get_data():
results = []
for i in range(1_000_000):
results.append(compute(i))
return results
# 生成器方式
def get_data_generator():
for i in range(1_000_000):
yield compute(i)
# 使用生成器
for data in get_data_generator():
process(data)
无限序列
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
# 永远不会内存溢出
fib = fibonacci()
for _ in range(1000):
print(next(fib))
实际节省内存测试
import sys
# 创建同等规模的列表和生成器
list_comprehension = [x for x in range(100_000)]
generator_expression = (x for x in range(100_000))
print(f"列表占用: {sys.getsizeof(list_comprehension)} bytes")
print(f"生成器占用: {sys.getsizeof(generator_expression)} bytes")
# 输出:
# 列表占用: 824464 bytes (约0.8MB)
# 生成器占用: 56 bytes
高级内存节省技巧
使用itertools
from itertools import islice, count, cycle
# islice:切片生成器,不创建中间列表
for item in islice(generator, 100):
print(item)
# count:无限计数器
for i in islice(count(10), 5):
print(i) # 10, 11, 12, 13, 14
管道式处理
def read_file(filename):
with open(filename) as f:
for line in f:
yield line.strip()
def filter_lines(lines):
for line in lines:
if 'ERROR' in line:
yield line
def parse_line(lines):
for line in lines:
yield parse(line)
# 链式处理,全程零内存开销
for error in parse_line(filter_lines(read_file('large.log'))):
report(error)
递归使用生成器
def tree_walk(node):
yield node
for child in node.children:
yield from tree_walk(child) # Python 3.3+
注意事项
不能重复使用
gen = (x for x in range(5)) print(list(gen)) # [0, 1, 2, 3, 4] print(list(gen)) # [] 已耗尽
需要重新生成
# 需要多次迭代时,需要重新创建生成器
for _ in range(3):
for item in (x for x in range(5)):
print(item, end=' ')
print()
# 输出: 0 1 2 3 4
# 0 1 2 3 4
# 0 1 2 3 4
不能随机访问
gen = (x for x in range(5)) # gen[2] # TypeError: 'generator' object is not subscriptable
何时使用生成器
| 场景 | 推荐方式 |
|---|---|
| 处理大文件 | 生成器 |
| 无限数据流 | 生成器 |
| 需要索引访问 | 列表 |
| 多次迭代 | 列表或重新创建生成器 |
| 数据量小(<1000) | 两者均可 |
性能权衡
- 内存节省:生成器完胜
- CPU效率:生成器略快(减少了内存分配开销)
- 灵活性:列表胜出(支持索引、切片等)
当处理大数据集、流式数据、不确定数据规模时,生成器是节省内存的最佳选择,对于小数据或需要频繁随机访问的场景,使用列表更合适。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播