Python3 迭代器与生成器

一、迭代器 (Iterator)

  1. 核心概念
    可迭代对象 (Iterable):可以被for循环遍历的对象(如list/str/tuple/dict/set)
    本质:内部实现了__iter__()方法
    迭代器 (Iterator):用来逐个取出元素、记住遍历位置的对象
    本质:同时实现__iter__() + next ()方法
    iter ():返回自己
    next ():返回下一个元素,没有则抛 StopIteration
    特点:
    只能往前,不能后退
    遍历一次就耗尽
    惰性取值(不一次性加载所有数据)
  2. 关键方法
    iter(可迭代对象) → 获取迭代器
    next(迭代器) → 取下一个元素
    遍历完会抛出:StopIteration 异常
  3. 极简示例
python 复制代码
lst = [1, 2, 3]
it = iter(lst)  # 获取迭代器

print(next(it))  # 1
print(next(it))  # 2
print(next(it))  # 3
# print(next(it))  # 报错 StopIteration
  1. 自定义迭代器(重点)
    必须实现两个方法:
    iter ():返回迭代器自身
    next():返回下一个值,结束抛StopIteration
python 复制代码
class MyIterator:
    def __init__(self):
        self.num = 1

    def __iter__(self):
        return self

    def __next__(self):
        if self.num > 3:
            raise StopIteration
        val = self.num
        self.num += 1
        return val

# 使用
for i in MyIterator():
    print(i)  # 1 2 3

二、生成器 (Generator)

  1. 核心概念
    生成器 = 优雅的迭代器
    一边循环一边计算,不一次性生成所有数据
    优点:省内存!适合大数据 / 无限序列
  2. 两种创建方式

① 生成器表达式(简单)

把列表推导式的 \[\] 改成 () 就是生成器

python 复制代码
g = (x for x in range(3))
print(next(g))  # 0
print(next(g))  # 1

② 生成器函数(重点)

使用 yield 关键字,不是 return

调用函数不执行代码,返回生成器对象

next() 时执行到 yield 暂停,返回值

再次 next() 从暂停处继续执行

python 复制代码
def gen():
    yield 1
    yield 2
    yield 3

g = gen()  # 得到生成器
print(next(g))  # 1
print(next(g))  # 2
  1. yield 工作原理
    调用函数 → 返回生成器,不运行
    next() → 运行到 yield 暂停,返回值
    再次 next() → 从暂停位置继续执行
    函数结束 → 自动抛 StopIteration
  2. send () 方法(进阶)
    send(value):可以向生成器传值
    第一次必须用 next() 或 send(None)

三、迭代器 vs 生成器 对比(必会)

特性 迭代器 生成器
写法 类实现__iter__+next 函数 + yield / 表达式()
代码量 极少
内存占用 较高 极低(惰性计算)
功能 基础迭代 功能更强,支持协程
使用场景 通用迭代 大数据、无限序列、协程

一句话总结:生成器就是简化版、高性能版的迭代器。

四、常用知识点

所有生成器都是迭代器,反之不成立

for 循环本质:自动调用 iter() + next() + 捕获异常

迭代器 / 生成器只能遍历一次,用完即废

总结

可迭代对象:能for循环 → 有__iter__()

迭代器:能next() → 有__iter__()+next ()

生成器:用yield的函数 → 最推荐使用

核心优势:惰性计算、节省内存

PS

什么是协程(Coroutine)?

可以暂停、可以恢复、用户态下切换的函数 = 协程

比线程轻量得多

不需要操作系统调度

遇到阻塞(IO、sleep)可以主动让出执行权

Python 中生成器是实现协程的基础

现代 Python 协程用 async/await,底层仍然基于生成器机制

简单理解:
函数可以暂停 → 去做别的事 → 再回来继续执行,这就是协程。

yield 关键字作用

核心作用 4 点:

  1. 让函数变成生成器
    函数里只要有 yield,调用它不再直接运行,而是返回生成器对象。
  2. 暂停函数执行
    执行到 yield 就停住,保存当前状态。
  3. 返回一个值
    yield x 会把 x 返回给调用者(next() 拿到)。
  4. 可以接收外部传入的值
    通过 send() 可以把值传给 yield,实现双向通信。
    极简记忆:
    yield = 暂停 + 返回值 + 可恢复

生成器为什么节省内存?

因为它是惰性计算(懒加载):

列表:一次性把所有元素创建好放内存

生成器:用到时才计算一个,用完就丢

不保存整个序列,只保存当前状态 + 计算规则

所以:

处理百万、亿级数据时,生成器几乎不占内存。

相关推荐
青梅味猪大肠14 分钟前
【深入浅出C++】为什么虚表指针可以解决菱形继承
开发语言·c++
潘潘的嵌入式日记25 分钟前
I²C 从机接收总被覆盖?双缓冲要在 STOP 时交接
c语言·开发语言·单片机
Lhan.zzZ1 小时前
QML 组件库:VS2022 + Qt 静态库方案
开发语言·c++·qt·visual studio
敲代码的嘎仔1 小时前
28届后端开发-海康威视日常实习一面(已OC)
java·开发语言·后端·面试·海康威视·实习·大厂
谢白羽2 小时前
SGLang的AWQ量化笔记
笔记·python·sglang
sakiko_3 小时前
OC基础语法(与Swift对比)-1
开发语言·ios·objective-c·swift
迷迭香yy3 小时前
基金档案数据工程实战从收入分析到持仓穿透的Python解析 IG50免费开源股票数据API接口
开发语言·python
清水白石0083 小时前
Python 类型设计深度解析:TypedDict 能否替代 dataclass?从 JSON 数据边界到 API 设计的最佳实践
java·python·json
晊晌_h3 小时前
嵌入式从0到精通——线程
java·开发语言·jvm
一木 之林3 小时前
五、C++ 新特性、关键字与编译原理(进阶)(二)
java·开发语言·c++