Python 迭代器与生成器

可迭代对象提供迭代器;迭代器实现 __next__;生成器用 yield 惰性产出状态机。

#type / concept #status / growing #tech / dev #resource / python #tech / lang / python

[!info] 关联笔记

Python 迭代器与生成器

这个概念为什么出现

for 能遍历文件行、查询结果、无限流,是因为迭代协议,不是因为它们都是 list。生成器让你用同步写法表达惰性流水线,避免一次装入内存。

[!abstract] 一句话理解 可迭代对象通过 __iter__ 返回迭代器;迭代器通过 __next__ 产出元素并在结束时抛 StopIterationyield 函数是生成器迭代器。

最小可运行示例

先把示例放进业务场景,再看代码:

场景:按批次惰性产出待同步订单 ID

# order_batches_gen.py
# 业务意图:把大列表切成固定批次,惰性产出。
# 教学点:
# - yield 生成器;
# - for 消费迭代器;
# - 耗尽后不可再取。

from typing import Iterator, Sequence


def batched(items: Sequence[str], size: int) -> Iterator[list[str]]:
    if size <= 0:
        raise ValueError("size must be positive")
    for i in range(0, len(items), size):
        yield list(items[i : i + size])


def main() -> None:
    orders = [f"O{i}" for i in range(1, 6)]
    gen = batched(orders, 2)
    print(next(gen))
    print(next(gen))
    print(list(gen))  # 剩余批次


if __name__ == "__main__":
    main()

建议运行:

python order_batches_gen.py

期望输出:

['O1', 'O2']
['O3', 'O4']
[['O5']]

结合场景再看三个关注点

  1. 批次按需产出,适合同步任务队列。
  2. next 与 for 都在推进同一迭代器状态。
  3. 生成器是一次性的;要重跑需重新调用函数。

核心概念与准确模型

flowchart LR
  Iterable -->|"iter()"| Iterator
  Iterator -->|"next()"| Item
  Iterator -->|"end"| StopIteration
  • iter(x) / next(it, default)
  • 生成器函数、生成器表达式
  • yield from 委托子迭代器

边界情况与反直觉行为

  1. list 是可迭代也可反复遍历;生成器不行。
  2. 在生成器内 return value 变成 StopIteration.value(少直接依赖)。
  3. 生成器 close/throw 用于协程风格控制(进阶)。

常见误区

[!warning] 常见误区:把生成器当列表返回多次使用 错误理解:变量里装着全部数据。
正确模型:装着“如何继续算”的状态机。

工程实践

  • 大文件按行迭代
  • 流水线:生成器链接
  • 需要多遍消费时 list(gen) 或重开

本节总结

迭代协议统一了 for 的世界;生成器是最省事的惰性工具。

自测题

  1. 可迭代与迭代器差别?
  2. 为什么 list(gen) 后 gen 空了?
参考答案
  1. 可迭代能提供迭代器;迭代器保持遍历位置并 next。
  2. 迭代器已耗尽。

延伸阅读与资料来源

资料类型支撑内容
Iterator types文档协议
Yield expressions规范yield
创建于 2026/7/15 更新于 2026/7/15