← [ BACK_TO_NOTES ]

Python 迭代器与生成器

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

#concept #growing #dev #python #python

[!info] related notes

Python 迭代器与生成器

这个概念为什么出现

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

[!abstract] 一句话理解 可迭代对象通常通过 __iter__ 提供迭代器;迭代器的 __iter__ 返回自身,__next__ 产出元素,耗尽时抛 StopIteration。调用含 yield 的生成器函数得到生成器迭代器,不立即执行函数体。

最小可运行示例

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

场景:按批次惰性产出待同步订单 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. 批次按需产出,但本例先构造了完整的 orders 列表;生成器保留其引用,每批还会创建 list,不代表输入流式读取或总内存恒定。
  2. next 与 for 都在推进同一迭代器状态。
  3. 生成器一次性消费;size 校验也要首次推进时才执行,调用 batched(orders, 0) 本身不会立即报错。

核心概念与准确模型

flowchart LR
  Iterable -->|"iter()"| Iterator
  Iterator -->|"next()"| Item
  Iterator -->|"end"| StopIteration
  • iter(x) / next(it, default);iter 还支持从索引 0 开始的旧式 __getitem__ 序列协议,不能仅凭是否定义 __iter__ 判断可迭代。
  • 生成器函数、生成器表达式
  • yield from 委托子迭代器

边界情况与反直觉行为

  1. list 是可迭代也可反复遍历;生成器不行。
  2. 同步生成器的 return value 成为结束时的 StopIteration.value;不要用显式 raise StopIteration 结束生成器,它逸出生成器体时会转为 RuntimeError。
  3. break 只停止消费,不保证立即关闭生成器。生成器持有文件等资源且可能提前退出时,需由拥有者显式 close 或使用 contextlib.closing;close 可触发已经进入的 try/finally。

常见误区

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

工程实践

  • 大文件按行迭代
  • 流水线:生成器链接
  • 多遍消费可在数据量有限时物化为 list,或重建数据源;list(gen) 会将所有剩余元素装入内存,无限流不能如此处理。

本节总结

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

自测题

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

延伸阅读与资料来源

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

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本