跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python算法

Python 迭代器和生成器详解

Python 中的迭代器与生成器机制。可迭代对象需实现__iter__方法,而迭代器还需实现__next__方法并维护内部状态。生成器作为特殊的迭代器,利用 yield 关键字实现惰性加载,有效节省内存。文章通过链表类示例对比了两者区别,展示了斐波那契数列生成及异常处理逻辑,并说明了 yield from 语法糖的使用场景。

清心发布于 2026/3/21更新于 2026/10/897 浏览

1. 迭代器

1.1 可迭代对象

可迭代对象指的是实现了 __iter__ 方法的对象,可以被 for 循环遍历的容器,比如一个列表,自定义的链表等。使用 iter() 方法获取它的迭代对象 (可以理解为链表的指针)。

1.2 迭代器

迭代器是指实现了 __iter__ 和 __next__ 方法的对象。__iter__ 返回它本身,确保每个单独的节点都是可以被迭代的,满足链表可以从第 n 个元素开始访问的需求;__next__ 返回它的下一个节点,如果已经遍历完毕则抛出 StopIteration 异常。

# 实现了__iter__方法,是一个可迭代对象,可以理解为是一个整的链表,但此时还不能单独访问其中的元素
class Node:
    def __init__(self, data):
        self.data = data
        self.next: Node | None = None

    def __iter__(self):
        return NodeIter(self)

# 是迭代器对象,可以理解为指向链表首元素的指针,通过这个指针遍历所有的链表元素
class NodeIter:
    def __init__(self, node: Node = None):
        self.current = node

    def __iter__(self):
        return self

    def __next__(self):
        if self.current is None:
            raise StopIteration
        else:
            node = self.current
            self.current = self.current.next
            return node

1.3 可迭代对象和迭代器的区别

  1. 协议不同:可迭代对象只需实现 __iter__(),迭代器需要实现 __iter__() 和 __next__()
  2. 状态:迭代器有内部状态(当前位置),可迭代对象通常没有
  3. 重用性:可迭代对象可多次遍历(每次获取新迭代器),迭代器遍历一次后耗尽
  4. 包含关系:所有迭代器都是可迭代对象,但并非所有可迭代对象都是迭代器

依旧以链表举例,整个链表是一个可迭代对象,遍历这个对象的时候实际上是通过一个指向链表首元素的指针不断地移动到下一个元素来完成的,这个指针就可以理解为迭代器。

2. 生成器

2.1 概念

生成器是一种特殊的迭代器,它通过 yield 关键字动态地返回值,而非一次性返回所有值,适合用来读取大文件或产生无限序列。生成器内部自动实现了 __iter__ 和 __next__。

当一个函数内部使用了 yield 关键字时,那么它就是一个生成器函数,此时函数的返回值不再是 return 后的返回值,而是类似于函数的对象:

<generator object fibonacci at 0x0000026E4B6D20A0>

以一个生成 n 个斐波那契的生成器举例:

def fibonacci(limit):
    """生成斐波那契数列"""
    a, b = 0, 1
    count = 0
    while count < limit:
        yield a
        a, b = b, a + b
        count += 1

当执行下面的代码时:

fibo = fibonacci(10)
print(fibo) # 输出:<generator object fibonacci at 0x0000026E4B6D20A0>
print(next(fibo)) # 输出 0
print(next(fibo)) # 输出 1
print(next(fibo)) # 输出 1
print(next(fibo)) # 输出 2

fibo 是一个生成器对象,这个对象可以生成 10 个斐波那契数,但不是同时生成在内存中,而是一个 next() 取回一个值,这个特性被称作'惰性加载'。执行第一个 next() 时,返回第一个 yield 后的值并且暂停函数的执行,等到第二次执行 next() 时从第一个 yield 后开始继续执行,也就是说,当我在第一个 yield 下面抛出异常,函数执行一次 next() 并不会报错,因为抛出异常语句并没有执行,第二次执行 next() 才会报错,比如下面的代码:

def generator1():
    print('第一个 yield 之前的语句块')
    yield 1
    print('第一个 yield 之后的语句块')
    print(1 / 0)
    print('第二个 yield 之前的语句块')
    yield 2
    print('第二个 yield 之后的语句块')

ge = generator1()
print(next(ge)) # 只执行 print(1 / 0) 之前的代码函数就被中断了,所以不会报错
print(next(ge)) # 回到第一个 yield 之后的代码继续执行,执行到 print(1 / 0) 语句,报错

如果生成器函数中有 return 语句,return 语句依旧有结束函数运行的作用,return 之后的语句不可达,但仍然遵循上面的中断原则,并且 return 后的值是抛出 StopIteration 异常时传递给调用者的值。

2.2 yield from

当我们的生成器的数据是从一个列表中取得并且每次返回一个元素时应该怎么写?

def generator():
    user_list = ["zhang", "li", "wang", "qian"]
    for username in user_list:
        yield username

ge = generator()
for i in ge:
    print(i)

yield from 就是简化上面的流程,提升生成器的效率,以上代码可以用下面的代码替代:

def generator():
    user_list = ["zhang", "li", "wang", "qian"]
    yield from user_list

ge = generator()
for i in ge:
    print(i)

目录

  1. 1. 迭代器
  2. 1.1 可迭代对象
  3. 1.2 迭代器
  4. 实现了iter方法,是一个可迭代对象,可以理解为是一个整的链表,但此时还不能单独访问其中的元素
  5. 是迭代器对象,可以理解为指向链表首元素的指针,通过这个指针遍历所有的链表元素
  6. 1.3 可迭代对象和迭代器的区别
  7. 2. 生成器
  8. 2.1 概念
  9. 2.2 yield from

更多推荐文章

查看全部
  • 人形运控部署框架汇总:rsl_rl 与 unitree_rl_gym 解析
  • OpenClaw 龙虾机器人本地部署与配置指南
  • Midjourney 12 组高质感风格参考代码推荐
  • 基于 Trae 插件 Builder 模式开发包粽子小游戏
  • RMBG-2.0接入Stable Diffusion工作流实现生成抠图合成一体化
  • 大模型本地部署与优化实战指南
  • Python 数据可视化绘图基础与实战指南
  • MCP 插件配置实战:browser-tools-mcp 集成指南
  • GitHub Copilot 专业版国内支付升级指南
  • 前端虚拟列表实现原理与优化实践
  • Z-Image-Turbo 极速云端创作室入门与提示词实战指南
  • 前端核心知识点与面试指南
  • 前端动画库选型:CSS、Framer、GSAP、React Spring
  • 服务器环境 VS Code GitHub Copilot 加载超时优化与修复方案
  • 链表相关算法题:队列安排与约瑟夫问题
  • 《ChatGPT 原理与应用开发》:大模型入门实战指南
  • C++ 串口应用开发详解:Qt、Boost 与 Modbus 实战
  • 详解 Redis 在 CentOS 上的安装与配置
  • Python+Flask+Vue 在线宠物医疗预约平台的设计与实现
  • OpenClaw 本地部署与飞书机器人接入指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online