Python3 入门教程
迭代器与生成器
本教程共 70 篇 · 第 26 篇 · 更新于 2026-07-22 · 约 3 分钟阅读
PythonPython3 入门教程迭代器生成器yieldyield from
26. 迭代器与生成器
本节目标:理解迭代器协议,掌握 yield 的用法,能用生成器处理大数据流。
迭代器是什么
迭代器是「能记住遍历位置」的对象。它有两个核心方法:
__iter__():返回迭代器自身__next__():返回下一个元素,没有时抛出StopIteration
>>> nums = [1, 2, 3]
>>> it = iter(nums) # 获取迭代器
>>> next(it)
1
>>> next(it)
2
>>> next(it)
3
>>> next(it)
StopIteration
Note迭代器只能往前,不能后退,也不能重复遍历。想再来一次,得重新
iter()。
for 循环的本质
for 循环底层就是迭代器:
for x in iterable:
print(x)
# 等价于
it = iter(iterable)
while True:
try:
x = next(it)
print(x)
except StopIteration:
break
自定义迭代器
实现 __iter__ 和 __next__ 方法:
class CountDown:
def __init__(self, start):
self.start = start
def __iter__(self):
return self
def __next__(self):
if self.start <= 0:
raise StopIteration
self.start -= 1
return self.start + 1
for n in CountDown(5):
print(n)
# 5 4 3 2 1
生成器函数
用 yield 关键字,可以更简单地把函数变成生成器:
def countdown(n):
while n > 0:
yield n
n -= 1
for x in countdown(5):
print(x)
# 5 4 3 2 1
Tip
yield会暂停函数执行并返回一个值,下次从暂停处继续。这比普通函数「一口气算完所有结果再返回」省内存得多。
生成器函数返回的是生成器对象:
>>> gen = countdown(3)
>>> gen
<generator object countdown at 0x...>
>>> next(gen)
3
>>> next(gen)
2
生成器表达式
前面推导式章节提过,圆括号包起来就是生成器表达式:
>>> gen = (x ** 2 for x in range(10))
>>> gen
<generator object <genexpr> at 0x...>
>>> sum(gen)
285
用生成器处理大文件
读取大文件时,不用一次性加载到内存:
def read_lines(filename):
with open(filename, 'r', encoding='utf-8') as f:
for line in f:
yield line.strip()
for line in read_lines('big_file.txt'):
process(line) # 逐行处理,内存只存一行
Tip文件对象本身就是迭代器,
for line in f已经是一行一行读了。但把逻辑封装成生成器函数,能让代码更清晰、更可复用。
生成器的数据传递
yield 不仅可以返回值,还能接收值:
def echo():
while True:
received = yield
print(f"收到: {received}")
e = echo()
next(e) # 启动生成器(或 e.send(None))
e.send("hello")
e.send("world")
# 收到: hello
# 收到: world
Warning生成器启动前必须先
next()或send(None),让执行流到第一个yield处。不然直接send会报错。
yield from
Python 3.3+ 的 yield from 可以把另一个生成器的值委托出来:
def sub_generator():
yield 1
yield 2
def main_generator():
yield 'a'
yield from sub_generator()
yield 'b'
print(list(main_generator()))
# ['a', 1, 2, 'b']
这在写协程、递归生成器时很方便。
什么时候用生成器
| 场景 | 推荐 |
|---|---|
| 数据量巨大,内存吃紧 | 生成器 |
| 需要惰性计算、按需取值 | 生成器 |
| 需要随机访问、多次遍历 | 列表 |
| 数据量小,操作简单 | 列表 |
Note生成器是惰性求值的,只能遍历一次。如果需要多次遍历或随机访问,转成列表:
list(generator)。但要确保数据量不会撑爆内存。
来源:参考了 runoob「Python3 迭代器与生成器」、liaoxuefeng「函数式编程」等,改写后所得。