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

迭代器是实现__iter__()和__next__()方法的对象,生成器是含yield的函数或生成器表达式创建的特殊迭代器;二者均惰性计算,节省内存。

Python 中的生成器和迭代器都实现惰性计算,即不一次性生*部数据,而是在需要时逐个产出,节省内存、提升效率。

什么是迭代器(Iterator)

迭代器是实现了 __iter__()__next__() 方法的对象。调用 iter() 得到迭代器,每次调用 next() 返回一个元素,直到抛出 StopIteration 异常。

  • 列表、字典、字符串等内置类型可被 iter() 转为迭代器
  • 迭代器只能单向遍历,不可重置(除非重新创建)
  • 本质是“状态机”,记住当前迭代位置

什么是生成器(Generator)

生成器是一种特殊的迭代器,由函数定义(含 yield)或生成器表达式(类似列表推导式但用圆括号)创建。函数执行到 yield 暂停,返回值并保存上下文;下次调用 next() 从中断处继续。

  • yield 让函数变成生成器函数,调用它返回生成器对象,不执行函数体
  • 生成器自动实现迭代器协议,无需手动写 __iter____next__
  • 适合处理大数据流、无限序列或需按需计算的场景

惰性计算的实际表现

对比 [x*2 for x in range(1000000)](列表推导)和 (x*2 for x in range(1000000))(生成器表达式):

  • 前者立刻分配约 8MB 内存(存 100 万个整数),后者只占几十字节
  • 生成器在 for 循环或 next() 调用时才真正计算下一个值
  • 若循环中途 break,后续值永远不会被计算

使用建议与注意事项

生成器和迭代器不是万能的,需注意适用边界:

  • 需要多次遍历?迭代器只能用一次,得重新创建或转成列表(但失去惰性优势)
  • 需随机访问(如 obj[5])?生成器不支持索引,应改用其他结构
  • 调试时想看全部内容?可用 list(gen) 强制展开,但仅限小数据量
  • 函数中混用 returnyield 是合法的(return 表示生成结束),但 return 后的值不会被 yield 出来