生成器 #
生成器是一种惰性计算的迭代器,使用yield关键字生成值。
一、基本语法 #
python
def my_generator():
yield 1
yield 2
yield 3
gen = my_generator()
print(next(gen)) # 1
print(next(gen)) # 2
print(next(gen)) # 3
# print(next(gen)) # StopIteration
# 使用for循环
for value in my_generator():
print(value)
二、生成器表达式 #
python
# 生成器表达式
gen = (x ** 2 for x in range(5))
print(list(gen)) # [0, 1, 4, 9, 16]
# 对比列表推导式
lst = [x ** 2 for x in range(5)] # 立即计算
# 生成器惰性计算,节省内存
gen = (x ** 2 for x in range(1000000)) # 几乎不占内存
三、yield的工作原理 #
python
def count_up_to(n):
count = 1
while count <= n:
yield count # 暂停并返回值
count += 1 # 下次从这里继续
for num in count_up_to(5):
print(num) # 1 2 3 4 5
四、生成器方法 #
4.1 send方法 #
python
def accumulator():
total = 0
while True:
value = yield total
if value is not None:
total += value
gen = accumulator()
print(next(gen)) # 0(初始化)
print(gen.send(10)) # 10
print(gen.send(5)) # 15
4.2 throw方法 #
python
def my_gen():
try:
yield 1
yield 2
except ValueError:
yield "捕获异常"
gen = my_gen()
print(next(gen)) # 1
print(gen.throw(ValueError)) # "捕获异常"
4.3 close方法 #
python
def my_gen():
try:
yield 1
yield 2
finally:
print("清理资源")
gen = my_gen()
print(next(gen)) # 1
gen.close() # 清理资源
五、实际应用 #
5.1 读取大文件 #
python
def read_large_file(filename):
with open(filename) as f:
for line in f:
yield line.strip()
for line in read_large_file("large.txt"):
process(line)
5.2 无限序列 #
python
def infinite_counter():
n = 0
while True:
yield n
n += 1
counter = infinite_counter()
print(next(counter)) # 0
print(next(counter)) # 1
print(next(counter)) # 2
5.3 斐波那契数列 #
python
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
fib = fibonacci()
for _ in range(10):
print(next(fib)) # 0 1 1 2 3 5 8 13 21 34
5.4 数据管道 #
python
def read_lines(filename):
with open(filename) as f:
for line in f:
yield line
def filter_comments(lines):
for line in lines:
if not line.strip().startswith('#'):
yield line
def strip_lines(lines):
for line in lines:
yield line.strip()
# 管道处理
pipeline = strip_lines(filter_comments(read_lines("file.txt")))
for line in pipeline:
print(line)
六、yield from #
python
def sub_gen():
yield 1
yield 2
def main_gen():
yield from sub_gen() # 委托给子生成器
yield 3
for value in main_gen():
print(value) # 1 2 3
七、生成器vs列表 #
python
# 列表:立即创建,占用内存
numbers_list = [x ** 2 for x in range(1000000)]
# 生成器:惰性计算,节省内存
numbers_gen = (x ** 2 for x in range(1000000))
# 生成器只能迭代一次
gen = (x for x in range(3))
print(list(gen)) # [0, 1, 2]
print(list(gen)) # [](已经迭代完)
八、总结 #
| 特点 | 说明 |
|---|---|
| 关键字 | yield |
| 惰性计算 | 按需生成 |
| 内存效率 | 节省内存 |
| 单次迭代 | 只能迭代一次 |
| 表达式 | (x for x in iter) |
最后更新:2026-03-16