生成器内存占用远低于列表,适合顺序遍历和流式处理;列表支持随机访问和重复遍历,适合需索引、切片或多次使用的场景;小数据量时差异不显著,应按实际需求选型。

Python列表和生成器在性能与内存使用上差异明显,关键看是否需要一次性持有全部数据。
内存占用:生成器明显更轻量
列表会立即创建并存储所有元素,占用连续内存空间;生成器只保存状态,每次调用 next() 才计算下一个值,内存几乎恒定。
- 例如:[x**2 for x in range(10**6)] 约占80MB内存(含对象开销)
- 而 (x**2 for x in range(10**6)) 内存占用通常不到1KB
- 数据规模越大,差距越显著,尤其处理GB级日志或传感器流时,生成器可避免内存溢出
访问模式决定选型:随机访问用列表,顺序遍历用生成器
列表支持索引、切片、重复遍历;生成器只能单向迭代一次,不支持 lst[5] 或 len()(除非转为列表)。
- 若需多次遍历或按位置取值(如统计中位数、画折线图),优先用列表
- 若只是“过一遍”做过滤、求和、写入文件(如 sum(x for x in data if x > 0)),生成器更高效
- 误对生成器多次迭代会导致第二次返回空结果,需注意逻辑陷阱
时间开销:生成器延迟计算,但总耗时未必更低
生成器把计算压力分摊到每次迭代,启动快、首项响应快;列表启动慢(全量计算+分配内存),但后续访问零开销。
立即学习“Python免费学习笔记(深入)”;
- 适合场景:Web流式响应、实时数据预处理、用户交互中“加载更多”
- 不适合场景:高频随机读取、需反复计算同一数据集的算法(如机器学习特征工程)
- 可混合使用:用生成器加载原始数据,加工后缓存为列表供后续快速访问
实用建议:从需求出发,不盲目追求“惰性”
小数据(sys.getsizeof() 和 memory_profiler 实测关键路径。
- 调试阶段可用 list(gen) 快速转成列表查看内容,但生产环境慎用
- 函数返回大量数据时,考虑将 return list(...) 改为 yield 逐个产出
- itertools 模块提供大量内存友好的工具(如 islice, chain),比手写循环更安全










