精通 Python yield:生成器 vs return 实战指南
精通 Python yield:生成器 vs return 实战指南
什么是 Python yield?
yield 关键字行为类似 return,但不立即返回值,而是返回一个可迭代的生成器对象。调用包含 yield 的函数时,执行在第一个 yield 处暂停,将控制权交还给调用者并返回生成器。后续调用 next() 或 for 循环会从该点恢复执行,产出下一个值。
核心要点
- yield 创建生成器,实现惰性求值。
- 生成器对大型或无限序列内存高效。
- 可用
for-in、list()或next()读取生成器。 - 生成器耗尽后不可复用;需再次调用函数。
语法
yield expression
实战示例:简单的 yield
def test_yield():
yield "Welcome to Guru99 Python Tutorials"
output = test_yield()
print(output)
输出:
<generator object test_yield at 0x00000028265EB9A8>
生成器对象持有产出的值。要访问它,需迭代:
for value in output:
print(value)
输出:
Welcome to Guru99 Python Tutorials
生成器详解
生成器函数是返回可迭代生成器对象的特殊函数。与普通函数返回单个值不同,生成器惰性产出值序列,仅在请求时生成每个值。
创建生成器函数
def generator_example():
yield "H"
yield "E"
yield "L"
yield "L"
yield "O"
for letter in generator_example():
print(letter)
输出:
H E L L O
普通函数 vs 生成器函数
对比以下两函数:
# 普通函数
def normal_test():
return "Hello World"
# 生成器函数
def generator_test():
yield "Hello World"
print(normal_test()) # → Hello World
print(generator_test()) # → <generator object generator_test>
普通函数在 return 处终止;生成器在 yield 处暂停,将控制权连同生成器对象交还调用者。
消费生成器
可通过以下方式从生成器拉取值:
for-in循环list()实例化所有值next()手动逐步
示例:偶数生成器
def even_numbers(n):
for x in range(n):
if x % 2 == 0:
yield x
print(list(even_numbers(10))) # → [0, 2, 4, 6, 8]
使用 for-in
for num in even_numbers(10):
print(num)
输出:
0 2 4 6 8
使用 next()
gen = even_numbers(10)
for _ in range(6):
try:
print(next(gen))
except StopIteration:
print("End of generator")
输出:
0 2 4 6 8 End of generator
生成器一次性用完即止
生成器完全迭代后即耗尽。再次迭代无产出,除非重新调用生成器函数。
gen = even_numbers(10)
for num in gen:
print(num)
print(list(gen)) # → []
yield 实战:斐波那契数列
def fibonacci_series(limit):
a, b = 0, 1
count = 0
while count < limit:
yield a
a, b = b, a + b
count += 1
fib = fibonacci_series(7)
for num in fib:
print(num)
输出:
0 1 1 2 3 5 8
调用包含 yield 的函数
下例用辅助函数求平方,生成器产出每个结果。
def square(n):
return n * n
def square_range(n):
for i in range(n):
yield square(i)
for value in square_range(10):
print(value)
输出:
0 1 4 9 16 25 36 49 64 81
何时用 yield 而非 return
- 处理大量或流式数据,一次性加载所有项不切实际。
- 生成潜在无限序列(如惰性文件读取器)。
- 改善大数据集的内存占用和启动时间。
- 需要暂停和恢复计算,而非仅返回最终值。
Yield vs Return – 快速参考
| Yield | Return |
|---|---|
| 返回生成器;迭代时恢复执行。 | 终止函数;立即返回单个值。 |
在每个 yield 暂停,节省内存。 | 为返回值分配内存。 |
| 适合大型或无限序列。 | 适合小型、离散结果。 |
| 大数据集执行时间更快。 | 处理海量数据可能有开销。 |
核心要点
- yield 产生生成器对象,而非值。
- 生成器惰性传递值,内存占用极小。
- 可通过
for-in、list()或next()读取值。 - 耗尽后需重新调用函数复用。
- 大数据或流式场景下 yield 优于 return。
Python
- Python Lambda匿名函数实战指南
- Python 生成器:高效迭代与进阶用例
- Python 闭包详解:嵌套函数如何捕获变量
- 精通 Python 装饰器:专家技巧增强函数
- Python strip() 方法完全指南:去除首尾空白与自定义字符实战
- Python len() 函数实战指南:测量字符串、列表、元组、字典等对象长度
- 精通 Python Lambda 函数:实用示例与最佳实践
- Python round() 函数详解与实战示例
- 精通 Python map() 函数:语法、示例与最佳实践
- Python collections.Counter:高效计数、更新与算术运算
- 精通 Python enumerate():为列表、元组、字符串、字典带索引循环
- Python time.sleep():为代码添加延迟的完整指南