Python 中的“迭代器”到底是什么
**迭代器(iterator)**是遵循“迭代器协议”的对象:
同时实现了 iter()(返回自身)和 next()(返回下一个元素,没元素时抛出 StopIteration)。
与之配套的是可迭代对象(iterable):只需实现 iter()(返回一个迭代器)或实现 getitem 的从 0 开始索引访问。
• 常见可迭代:list/tuple/dict/set/str/range、pandas 的一些容器等。
• 常见迭代器:生成器对象(yield 的返回值)、itertools 里的大多数对象、文件对象(逐行读)、enumerate/zip/map/filter 的返回值等。
区分要点:
• 可迭代可以“被迭代”,每次调用 iter(obj) 会拿到新的迭代器;
• 迭代器是“一次性流”,自己就是迭代器(iter(it) is it),用过就耗尽。
⸻
为什么要用迭代器
• 惰性计算:按需产出元素,省内存(能处理“无限序列”或超大数据)。
• 统一协议:for 循环、推导式、sum/list/tuple/set、any/all 等都基于迭代器协议工作。
• 可组合:配合 itertools 进行高效的数据管道式处理。
⸻
快速示例
- 判断“可迭代”还是“迭代器”
from collections.abc import Iterable, Iterator
isinstance([1,2,3], Iterable) # True
isinstance([1,2,3], Iterator) # False
it = iter([1,2,3])
isinstance(it, Iterator) # True
next(it) # 1
- 自定义迭代器(类实现协议)
class Countdown:
def __init__(self, n): self.n = n
def __iter__(self): return self # 迭代器需返回自己
def __next__(self):
if self.n <= 0:
raise StopIteration
self.n -= 1
return self.n + 1
for x in Countdown(3): # 3, 2, 1
print(x)
- 生成器(最常用的迭代器)
def fib(limit):
a, b = 0, 1
while a < limit:
yield a # 函数含 yield → 返回“生成器对象”(迭代器)
a, b = b, a + b
for x in fib(10):
print(x)
- iter(callable, sentinel):把函数包装成迭代器
# 反复调用 read(8) 直到返回空字节串为止
chunks = iter(lambda: f.read(8), b"")
for chunk in chunks:
...
⸻
常见坑 & 小贴士
• 迭代器用过即空:需要“再来一遍”时,对可迭代重新 iter(),不要复用已耗尽的迭代器。
• dict 的迭代默认是键;for k in d: 等价于 for k in d.keys():。
• 想要列表再物化:list(iterator_or_iterable);否则尽量保持惰性以节省内存。
• 文件对象是迭代器:for line in open(“x.txt”): 会逐行读取,内存友好。
⸻
一句话总结
迭代器 = 按需产出元素的“一次性流”;可迭代 = 能提供迭代器的容器或对象。
Python 的循环与数据管道都围绕这个简单的协议构建,理解它就掌握了 Python 遍历与惰性计算的核心。

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



