Python 迭代器和生成器到底啥区别?3 个例子讲透,别再背概念了

简介: 迭代器和生成器不是并列关系——生成器是迭代器的一种“偷懒写法”。3 个例子讲透:迭代器是“会挨个吐值的对象”,生成器是用 yield 现写现用的那种,最大区别是它懒,要一个才生一个。

Python 迭代器和生成器到底啥区别?3 个例子讲透,别再背概念了

系列:Python 底层设计逻辑|类型:原理拆解型|分发:CSDN / 掘金 / 51CTO / 阿里云 / 知乎(回答)
字数:约 1600 字

结论先行:迭代器(iterator)和生成器(generator)不是并列关系——生成器是迭代器的一种"偷懒写法"。所有生成器都是迭代器,但迭代器不一定是生成器。一句话区分:迭代器是"会挨个吐值的对象"(实现 __iter__ + __next__),生成器是用 yield 或生成器表达式"现写现用"造出的那种迭代器,最大的不同是它懒,要一个才生一个,不占内存。


1. 先搞清:什么是迭代器

能 for x in obj 挨个取值的对象,都叫"可迭代对象"(iterable,有 __iter__)。而迭代器是"被迭代时记住自己走到哪"的那个东西——它多了个 __next__,每次调用吐下一个,吐完抛 StopIteration。

lst = [1, 2, 3]
it = iter(lst)          # list 是可迭代对象,iter() 造出它的迭代器
print(next(it))          # 1
print(next(it))          # 2

关键点:list 本身不是迭代器(它可被多次 iter()),但 it 是。for 循环干的事,本质就是反复 next() 直到 StopIteration。

2. 生成器:用 yield 写的迭代器

手写一个完整的迭代器类,要实现 __iter__ 和 __next__,还要自己存状态——挺啰嗦。生成器让你用 yield 把函数变成迭代器,状态由 Python 自动保存:

def gen():
    for i in range(3):
        yield i * i

g = gen()                # g 就是一个生成器对象(也是迭代器)
print(next(g))           # 0
print(next(g))           # 1
print(next(g))           # 4

为什么方便:yield 每次"暂停"把值交出来,下次 next() 从暂停处继续。你不用手动管下标、不用存列表,函数体就是状态机。

3. 核心差别:一个在内存,一个"现生现用"

这是最该记住的一点,用大文件举例:

# 迭代器(但提前把 100 万个平方全算好塞进列表)—— 占内存
def squares_list(n):
    return [i*i for i in range(n)]

# 生成器 —— 要一个才算一个,内存几乎为 0
def squares_gen(n):
    for i in range(n):
        yield i*i

for x in squares_gen(1_000_000):
    if x > 100:
        break

差别:列表版本先把一百万个数全造出来(几十 MB);生成器版本算到 x>100 就停,后面根本没算。这就是"懒求值"的价值——处理大文件、无限序列、流式数据时,生成器是刚需。

4. 生成器表达式:更短的写法

gen_expr = (i*i for i in range(1000000))   # 注意是 () 不是 []
print(next(gen_expr))                       # 0

对照:[] 是列表推导(一次性全算),() 是生成器表达式(懒)。一个占内存,一个不占,写法只差一对括号。

5. 生成器的"一次性"陷阱

迭代器和生成器都只能走一遍——走完就空了,得重新造:

g = squares_gen(3)
list(g)                  # [0, 1, 4]
list(g)                  # []  ← 空了!生成器已耗尽

坑点:把生成器当列表反复用,第二次永远拿到空。需要重复遍历就转成 list,或重新调用函数再造一个。


对照表:一眼分清

维度 可迭代对象 迭代器 生成器
能否 for ✅ ✅ ✅
有 __next__ ❌(需 iter() 造) ✅ ✅
是否"懒" 否 看实现 ✅ 一定是
写法 list/str 等 手写类 yield / () 表达式
遍历遍数 无限次 一遍 一遍

排错清单(收藏级)

  • 生成器第二次遍历是空:它一次性,重用时 list() 或重新调用函数。
  • yield 和 return 混用:return 在生成器里只用来结束并带值到 StopIteration,别当普通返回值。
  • 大列表爆内存:把 [... for ...] 改成 (... for ...),瞬间省内存。
  • 生成器里改外部变量小心:它是惰性执行的,循环体里的副作用会"延迟"到被 next() 时才发生。
  • next() 超界报 StopIteration:用 for 或在 next(g, default) 给默认值兜底。

一句话记住:迭代器是"会走路的对象",生成器是"用 yield 写的、懒的迭代器"。背概念不如记这句——要一个才生一个的,就是生成器。

相关文章
|
19天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
8783 25
|
17天前
|
人工智能 并行计算 PyTorch
秋叶 ComfyUI 2026 整合包 v3.2 完整部署教程:Python 3.13 + Torch 2.13 全栈升级
秋叶aaaki ComfyUI 2026年8月整合包v3.2正式发布!全面升级Python 3.13.11、PyTorch 2.13.0+cu130及ComfyUI v0.30.2,原生支持MiniMax H3、Wan 2.2、Qwen-Image-2.1等2026主流音视频/图像模型,解压即用,无需环境配置。
3344 15
|
17天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
2194 4
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
|
11天前
|
人工智能 Linux 开发者
【2026国内使用】Codex安装过程一篇讲透(Win/Mac/Linux全支持)
Codex是OpenAI推出的AI编程智能体,可读取本地项目、理解需求并自动修改代码。支持桌面GUI、命令行(CLI)及VS Code/Cursor插件三种形态,覆盖可视化操作、终端高效开发与编辑器无缝集成场景,助开发者用自然语言驱动编码全流程。(239字)
【2026国内使用】Codex安装过程一篇讲透(Win/Mac/Linux全支持)
|
17天前
|
云安全 人工智能 安全
|
3天前
|
人工智能 JSON 自然语言处理
2026 年 Jev 决策模型深度拆解:原理解读、实战测评与保姆级落地教程
有一款特殊AI模型在开发者圈子刷屏,它摒弃传统大模型擅长的对话聊天能力,专注做高速结构化决策,它就是TypeSafe AI推出的Jev模型。该模型由ChatGPT共同发明人Diogo Almeida主导研发,定位为**System One Model(系统一模型)**,对标人类大脑快速直觉判断的思维模式,在响应延迟、调用成本、结构化输出稳定性上相比传统生成式大模型有着巨大差异。本文会完整拆解Jev底层原理、三大核心原语能力、适用业务场景,同时提供可直接运行的curl、Python代码示例,并且结合多组实测数据,客观分析模型优势与能力边界,帮助普通开发者和AI应用从业者快速上手落地。
363 1
|
6天前
|
人工智能 Linux Windows
千问办公(QwenWork)官网入口:其实有2个,一个是网页端千问办公,一个是介绍指南页面
千问办公(QwenWork)是阿里云推出的AI智能办公平台,支持网页端直接使用及Windows/Mac/Linux客户端下载。提供PPT生成、财报分析、网页搭建等AI功能,个人版免费,企业版198元/席/月。详情见官网qwenwork.cn或阿里云产品页。
803 0
千问办公(QwenWork)官网入口:其实有2个,一个是网页端千问办公,一个是介绍指南页面