Python 可迭代对象、迭代器、生成器的区别与联系
1. 可迭代对象 (Iterable)
- 定义:实现了
__iter__()方法(或__getitem__()方法)的对象 - 核心特性:
- 可被用于
for循环、列表推导式等迭代场景 - 每次迭代会创建新的迭代器
- 可被用于
- 常见类型:
list, tuple, str, dict, set, range, file objects - 生命周期:
- 可重复遍历(每次遍历都会创建新迭代器)
- 不保存迭代状态
- 原理验证:
nums = [1, 2, 3] print(hasattr(nums, '__iter__')) # True (是可迭代对象) print(hasattr(nums, '__next__')) # False (不是迭代器)
2. 迭代器 (Iterator)
- 定义:实现了
__iter__()和__next__()方法的对象 - 核心特性:
- 有状态:记录当前迭代位置
- 惰性求值:按需生成元素
- 一次性:遍历完成后无法重启
- 生命周期:
nums = [1, 2, 3] it = iter(nums) # 从可迭代对象创建迭代器 print(next(it)) # 1 print(next(it)) # 2 print(next(it)) # 3 print(next(it)) # ❌ 抛出 StopIteration - 特点验证:
print(it is iter(it)) # True (迭代器的 __iter__() 返回自身)
3. 生成器 (Generator)
- 定义:使用
yield关键字创建的特殊迭代器 - 核心特性:
- 延迟计算:运行时动态生成值(节省内存)
- 状态暂停:每次
yield暂停执行,保留局部变量状态 - 一次性使用:与迭代器相同
- 创建方式:
# 生成器函数 def count_down(n): while n > 0: yield n # 暂停并返回值 n -= 1 # 生成器表达式 gen = (x**2 for x in range(5)) - 使用示例:
gen = count_down(3) print(next(gen)) # 3 print(next(gen)) # 2 print(next(gen)) # 1
三者关系图解
[可迭代对象] (如 list)
│
▼ 通过 iter() 创建
[迭代器] (如 list_iterator)
│
▼ 特殊形式
[生成器] (含 yield 的函数)
核心区别总结
| 特性 | 可迭代对象 | 迭代器 | 生成器 |
|---|---|---|---|
| 实现方法 | __iter__() | __iter__() + __next__() | yield 关键字 |
| 内存占用 | 存储所有元素 | 单元素 + 状态 | 单元素 + 执行状态 |
| 遍历次数 | 可重复遍历 | 仅一次 | 仅一次 |
| 状态保存 | ❌ 无状态 | ✅ 记录位置 | ✅ 完整执行状态 |
| 创建方式 | 直接构造 | iter(可迭代对象) | 函数含 yield 或生成器表达式 |
| 典型代表 | [1,2,3], "abc" | file.readlines() | (x for x in range(n)) |
| 是否懒加载 | ❌ | ✅ | ✅ |
| 元素生成时机 | 预先创建 | 按需创建 | 按需创建 |
转换关系示例
# 可迭代对象 → 迭代器
nums = [1, 2, 3] # 可迭代对象
it = iter(nums) # 创建迭代器
# 生成器 → 迭代器
def gen_func(): # 生成器函数
yield 1
yield 2
gen = gen_func() # 生成器(也是迭代器)
print(next(gen)) # 1
# 迭代器 → 可迭代对象 (所有迭代器都是可迭代对象)
for x in it: # 可直接用于迭代
print(x)
为什么需要生成器?
内存优化案例:读取 10GB 日志文件
# 传统方式(内存爆炸):
with open("huge.log") as f:
lines = f.readlines() # 一次性加载所有内容
# 生成器方案(内存友好):
def read_lines(filename):
with open(filename) as f:
for line in f: # 每次只读一行
yield line
for line in read_lines("huge.log"):
process(line) # 逐行处理
关键结论
- 所有生成器都是迭代器(实现了
__iter__和__next__) - 所有迭代器都是可迭代对象(但反之不成立)
- 生成器是创建迭代器的最简洁方式,尤其适合:
- 处理大数据流
- 实现无限序列
- 管道式数据处理
1687

被折叠的 条评论
为什么被折叠?



