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