Python生成器和迭代器的核心价值在于惰性计算——不提前生成全部数据,而是在需要时才产出下一个值,节省内存、提升响应速度,适合大数据流、无限序列或I/O密集型任务。

Python生成器和迭代器的核心价值在于惰性计算——不提前生成全部数据,而是在需要时才产出下一个值。这节省内存、提升响应速度,特别适合处理大数据流、无限序列或I/O密集型任务。
迭代器:支持next()的“一次消耗”对象
迭代器是实现了__iter__()和__next__()方法的对象,每次调用next()返回一个元素,耗尽后抛出StopIteration。它本身不存储全部数据,只保存当前状态。
- 内置容器(如list、str、dict)可被
iter()转为迭代器 - 手动实现迭代器需管理索引/状态,较繁琐,一般推荐用生成器替代
- 典型用途:逐行读大文件(
for line in open('big.log'):背后就是文件迭代器)
生成器:用yield写的轻量迭代器
生成器函数写起来更简洁:函数中只要含yield语句,调用它就返回生成器对象(即迭代器),而非直接执行函数体。
-
yield暂停函数并交出值,下次从暂停处继续执行 - 无需手动实现
__next__(),Python自动处理状态保存与恢复 - 示例:生成斐波那契数列前n项(但只需前10项时,不会算到第1000项)
def fib_gen(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
只取前5个,后面根本不会计算
for x in fib_gen(1000):
if x > 100: break
print(x) # 输出 0 1 1 2 3 5 8 13 21 34 55 89
惰性计算的实际好处
不是“炫技”,而是解决真实瓶颈:
立即学习“Python免费学习笔记(深入)”;
-
内存友好:读取GB级日志文件时,用
open().readlines()会一次性加载全部进内存;而用for line in file:(本质是迭代器)只存当前行 -
延迟执行:API分页请求可封装为生成器,每调用一次
next()才发一次HTTP请求,避免预加载所有页 -
组合灵活:多个生成器可链式调用(如
filter、map返回的也是惰性迭代器),形成数据流水线,全程不构建中间列表
注意:生成器只能遍历一次
生成器对象是单次使用的。遍历完即空,再次遍历时不会重头开始,而是立即结束。
- 想重复使用?要么重新调用生成器函数,要么转成
list(但会失去惰性优势) - 调试时误用
list(gen)可能触发全部计算,导致卡顿或OOM,要小心 - 可用
itertools.tee()复制迭代器,但会缓存已产生的值,权衡内存与复用性










