Python 生成器:高效迭代与进阶用例
Python 生成器
了解 Python 生成器如何简化迭代、减少样板代码并改善内存使用,优于传统迭代器。
什么是生成器?
在 Python 中构建自定义迭代器通常需要实现 __iter__() 和 __next__() 的类,管理内部状态,并在结束时引发 StopIteration。生成器消除这些样板代码,让你编写简单函数逐个产出值。
简而言之,生成器是返回迭代器的函数。函数体惰性执行,每次 yield 暂停,后续调用恢复。
在 Python 中创建生成器
定义生成器像写普通函数,将 return 替换为 yield:
def my_gen():
n = 1
print('This is printed first')
yield n
n += 1
print('This is printed second')
yield n
n += 1
print('This is printed at last')
yield n
调用 my_gen() 返回迭代器,仅在调用 next() 时开始执行。
a = my_gen()
next(a) # 打印第一条消息并返回 1
next(a) # 打印第二条消息并返回 2
next(a) # 打印最后消息并返回 3
next(a) # 引发 StopIteration
局部变量在 yield 间保持,但生成器只能迭代一次。重新开始需创建新实例。
因生成器是迭代器,可直接循环:
for item in my_gen():
print(item)
常见生成器模式
反转字符串
def rev_str(s):
for i in range(len(s)-1, -1, -1):
yield s[i]
for char in rev_str('hello'):
print(char)
适用于任何可迭代对象(列表、元组等)。
生成器表达式
匿名生成器可用圆括号创建,类似列表推导式:
my_list = [1, 3, 6, 10]
# 列表推导式
squares_list = [x**2 for x in my_list]
# 生成器表达式
squares_gen = (x**2 for x in my_list)
print(squares_list)
print(squares_gen)
生成器按需产出值:
a = (x**2 for x in my_list)
print(next(a)) # 1
print(next(a)) # 9
print(next(a)) # 36
print(next(a)) # 100
next(a) # StopIteration
生成器表达式可直接传给 sum 或 max 等函数,无需外层括号。
为什么使用生成器?
- 简洁实现:用几行代码替代冗长迭代器类。
- 内存高效:逐个产出项,适合大序列或无限序列。
- 无限流:表示无尽数据源(如
while True: yield)。 - 管道组合:链式多生成器实现清晰可读的数据处理。
示例:2 的幂
def pow_two_gen(max_n=0):
n = 0
while n < max_n:
yield 2 ** n
n += 1
示例:斐波那契数平方求和
def fibonacci_numbers(count):
a, b = 0, 1
for _ in range(count):
a, b = b, a + b
yield a
def square(nums):
for n in nums:
yield n ** 2
print(sum(square(fibonacci_numbers(10)))) # 4895
生成器为广泛迭代场景提供优雅、高效、可维护的代码。
Python
- 精通Python运算符:全面指南
- 精通Python函数参数:位置、关键字与默认参数
- 精通 Python 字典:创建、操作与进阶技巧
- Python 生成器:高效迭代与进阶用例
- Python 闭包详解:嵌套函数如何捕获变量
- 精通 Python 装饰器:专家技巧增强函数
- 精通 Python Lambda 函数:实用示例与最佳实践
- Python abs() 函数:计算数字与复数的绝对值
- Python round() 函数详解与实战示例
- 精通 Python map() 函数:语法、示例与最佳实践
- 精通 Python yield:生成器 vs return 实战指南
- 精通 Python enumerate():为列表、元组、字符串、字典带索引循环