Python

37|迭代器与生成器的按需取值

面向按顺序学习 Python 的初学者,本篇在第 18、22、35 篇知识上,帮助读者理解 iter、next 和 yield 的执行状态。

◉ 1.2k 字◌ 8 分钟♙ 郑在混

这套课程按知识依赖排列。本篇的前置知识是:第 18、22、35 篇。学完后,你应该能够理解 iter、next 和 yield 的执行状态。

本篇要解决的问题

本篇只处理“迭代器与生成器的按需取值”这一件事。示例基于 Python 3.14.6,在 macOS 环境核验;除明确标注的终端命令外,代码本身只使用 Python 标准能力。

先看清一个容易误解的细节

生成器每次只产生一个值

生成器运行到 yield 产生一个值并暂停,下一次请求时从暂停位置继续,而不是重新从函数第一行开始。

核心概念

  • iter() 从可迭代对象取得迭代器,next() 请求下一个值。
  • 没有更多值时迭代器抛出 StopIterationfor 会自动处理。
  • 生成器适合按需产生数据,但不是所有列表都需要改成生成器。

跟着示例运行

把下面代码保存到本课脚本并运行:

def countdown(start):
    current = start
    while current > 0:
        yield current
        current = current - 1

iterator = countdown(3)
print(next(iterator))
print(next(iterator))
print(next(iterator))

预期结果:

3
2
1

输出中包含环境路径、集合元素或日志格式时,具体文字和顺序可能随本机环境变化;判断是否成功应以本篇说明的关键结果为准。

按执行顺序拆开看

  1. 调用 countdown(3) 返回生成器对象,函数体还未运行。
  2. 每次 next() 运行到下一个 yield 并暂停,局部变量 current 和执行位置被保留。

再看一个具体细节

生成器的暂停位置可以展开成多次 next() 的时间线。

多次 next 推进同一个生成器

每次请求只推进到下一个 yield;局部变量保留,代码不会从函数开头重新运行。

初学者容易混淆的地方

  • 把生成器当列表重复遍历;多数生成器消耗后不能自动回到开头。
  • 在需要随机访问和多次读取的小数据上强行使用生成器,增加理解成本。

练习

  1. 编写产生 1 到指定上限偶数的生成器。
  2. for 遍历生成器,比较手动 next() 的差异。

练习应先独立完成,再通过增加 print 输出或检查文件内容观察中间状态。当前课程尚未讲到的能力,不要求提前搜索复杂写法。

本篇边界

本篇目标是理解 iter、next 和 yield 的执行状态。没有展开的高级机制会放到后续课程;先确保能够解释示例中每一行代码,再进入下一篇。

相关文章

© 2026 郑在混知识库 · 已运行 46 天 · 豫ICP备2026037626号-1