生成器是简化迭代器编写的语法糖,本质为返回生成器对象的函数,用yield暂停执行并自动维护状态;所有生成器都是迭代器,但反之不成立。

迭代器和生成器都用于按需获取数据,但生成器是迭代器的语法糖,本质是简化了迭代器的编写过程。
核心概念不同
迭代器是一个实现了 __iter__() 和 __next__() 方法的对象,调用 next() 时逐个返回元素,耗尽后抛出 StopIteration 异常。生成器是一种特殊的函数,使用 yield 关键字暂停并返回值,每次调用 __next__() 时从上次暂停处继续执行。
- 所有生成器都是迭代器(可直接用于 for 循环或 next()),但不是所有迭代器都是生成器(比如手动实现的类迭代器)
- 生成器函数被调用时并不执行,而是返回一个生成器对象;只有第一次调用 __next__() 才开始运行到第一个 yield
- 生成器对象内部自动维护状态(局部变量、执行位置等),无需手动保存上下文
写法与可读性差异明显
用类实现迭代器需要显式管理状态,代码冗长;生成器用函数 + yield 表达逻辑更直观。
- 类迭代器示例:需定义 __init__ 初始化状态,__iter__ 返回 self,__next__ 控制流程和边界
- 生成器示例:几行 yield 就能替代几十行类代码,比如 def fib(): a, b = 0, 1; while True: yield a; a, b = b, a+b
- 生成器支持表达式写法(生成器表达式),如 (x**2 for x in range(10)),比列表推导式更省内存
内存与执行时机关键区别
生成器是惰性求值的典型代表,只在需要时计算下一个值;而普通迭代器是否惰性取决于具体实现,但生成器天然具备该特性。
立即学习“Python免费学习笔记(深入)”;
- 生成器不会一次性生成全部结果,适合处理大数据流、无限序列或 I/O 流式读取
- 列表推导式 [x*2 for x in range(1000000)] 立即分配百万级内存;生成器表达式 (x*2 for x in range(1000000)) 几乎不占额外内存
- 生成器函数中 yield 后的代码可能永不执行(如提前 break 或异常退出),提升灵活性
生命周期与复用性限制一致
迭代器和生成器对象都是一次性的:遍历结束后不可重用,再次调用 next() 会触发 StopIteration。
- 想多次使用,需重新创建(对生成器是重新调用函数;对类迭代器是新建实例)
- 无法通过 seek 或 reset 重置位置,这是迭代协议的设计约束,不是 bug
- 若需重复遍历,可考虑转为 tuple/list(小数据),或封装成支持多次调用的工厂函数
理解两者的联系与分工,比死记定义更重要:生成器让写迭代器变得简单,而迭代器协议是 Python 统一循环机制的底层基础。










