Python生成器与迭代器应用_惰性计算说明【教程】

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

惰性计算的实际好处

不是“炫技”,而是解决真实瓶颈:

  • 内存友好:读取GB级日志文件时,用open().readlines()会一次性加载全部进内存;而用for line in file:(本质是迭代器)只存当前行
  • 延迟执行:API分页请求可封装为生成器,每调用一次next()才发一次HTTP请求,避免预加载所有页
  • 组合灵活:多个生成器可链式调用(如filtermap返回的也是惰性迭代器),形成数据流水线,全程不构建中间列表

注意:生成器只能遍历一次

生成器对象是单次使用的。遍历完即空,再次遍历时不会重头开始,而是立即结束。

  • 想重复使用?要么重新调用生成器函数,要么转成list(但会失去惰性优势)
  • 调试时误用list(gen)可能触发全部计算,导致卡顿或OOM,要小心
  • 可用itertools.tee()复制迭代器,但会缓存已产生的值,权衡内存与复用性