迭代器和生成器的区别与联系
目录
1.可迭代对象 (Iterable)
2.迭代器 (Iterator)
3.生成器 (Generator)
3.1生成器函数 vs 生成器表达式
4.三者之间的联系与区别
5.关系图(帮助你一眼看懂)
6.核心结论(记住这三句话)
1.可迭代对象 (Iterable)
定义:
实现了 __iter__()
方法的对象,可以被 iter()
转换成迭代器。
特点:
- 只能通过
iter()
生成迭代器,不能直接next()
。 - 常见例子:
list
、tuple
、str
、dict
、set
、range
。 for
循环背后就是在调用iter()
得到迭代器,然后不断next()
。
示例:
nums = [1, 2, 3] # list 是可迭代对象
it = iter(nums) # 调用 __iter__ 得到迭代器
print(next(it)) # 1
2.迭代器 (Iterator)
定义:
同时实现了 __iter__()
和 __next__()
方法的对象。
特点:
- 可以直接用
next()
获取下一个值。 - 取尽所有元素后,会抛出
StopIteration
。 - 迭代器本身也是可迭代对象(它的
__iter__()
返回自己)。 - 可以通过
iter()
从可迭代对象获得迭代器,或者手写迭代器类。
示例:
# 从可迭代对象得到迭代器
it = iter([1, 2, 3])
print(next(it)) # 1# 手写迭代器类
class MyIterator:def __init__(self):self.n = 0def __iter__(self):return selfdef __next__(self):if self.n < 3:value = self.nself.n += 1return valueelse:raise StopIterationit2 = MyIterator()
print(next(it2)) # 0
3.生成器 (Generator)
定义:
一种特殊的迭代器,通过 函数 + yield
创建,Python 自动帮我们实现 __iter__()
和 __next__()
。
特点:
- 生成器对象既是迭代器,也是可迭代对象。
- 每次执行到
yield
暂停,返回值,下次从暂停处继续执行。 - 自动处理状态保存和
StopIteration
,写起来更简洁。
示例:
def my_gen():yield 0yield 1yield 2gen = my_gen() # 直接就是迭代器
print(next(gen)) # 0
print(next(gen)) # 1
3.1生成器函数 vs 生成器表达式
对比点 | 生成器函数 | 生成器表达式 |
定义方式 |
| 圆括号 |
代码结构 | 支持多行、复杂逻辑 | 一行表达式,简洁 |
可读性 | 更适合复杂逻辑 | 更适合简单逻辑 |
可传参 | 可以通过调用函数传入参数 | 参数一般在表达式里定义 |
返回值 | 返回生成器对象 | 返回生成器对象 |
它们的联系:
- 本质相同:两者返回的都是生成器对象,本质上都是迭代器。
- 使用方式相同:都可以用
next()
、for
循环来取值。 - 选择依据:
-
- 如果逻辑简单,用生成器表达式。
- 如果逻辑复杂(需要多行代码、条件分支等),用生成器函数。
4.三者之间的联系与区别
特性 | 可迭代对象 (Iterable) | 迭代器 (Iterator) | 生成器 (Generator) |
| 有 | 有 | 自动实现 |
| 没有 | 有 | 自动实现 |
是否可直接 | 否 | 是 | 是 |
状态保存 | 不保存 | 手动维护 | 自动维护 |
停止迭代方式 | 需先转迭代器再判断 | 手动抛 | 自动抛出 |
创建方式 | list、tuple 等内置类型 | 手写类 or | 函数+ |
5.关系图(帮助你一眼看懂)
可迭代对象 (Iterable)
│ 有 __iter__()
▼
iter() 函数
▼
迭代器 (Iterator)
│ 有 __iter__() 和 __next__()
│ 可用 next() 获取值
│
└─> 生成器 (Generator) 是一种特殊的迭代器
(自动实现 __iter__ 和 __next__)
6.核心结论(记住这三句话)
- 可迭代对象:有
__iter__
,不能直接next()
,要先用iter()
转换。 - 迭代器:有
__iter__
+__next__
,能直接next()
,可以手写也可以用iter()
获得。 - 生成器:就是“自动实现了迭代器协议”的函数产物,写起来更简洁。
这样梳理之后,你会发现:
- 生成器 = 自动实现的迭代器
- 迭代器 = 可以手写,也可以由
iter()
或生成器自动得到 - 可迭代对象 = 可以转换成迭代器的对象