Python生成器是什么?
Python生成器允许我们在需要时才生成值,而不是一次性创建所有值,这在处理大规模数据或者无限序列时尤为重要(其实就是Python比较占内存资源,处理不了大规模数据而设计的一种机制,数据按需生成)
生成器函数:yield关键字的魔法
生成器函数是定义生成器最直接的方式,它与普通函数的区别在于使用yield关键字而非return。当调用生成器函数时,它不会立即执行,而是返回一个生成器对象.
# 示例:生成斐波那契数列的生成器函数
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
# 使用生成器
fib_gen = fibonacci()
print(next(fib_gen)) # 输出: 0
print(next(fib_gen)) # 输出: 1
print(next(fib_gen)) # 输出: 1
print(next(fib_gen)) # 输出: 2
生成器函数的核心特性:
- 执行yield时暂停,保存当前状态
- 再次调用next()时从暂停处继续执行
- 状态保存包括局部变量、执行位置
生成器表达式
生成器表达式提供了一种更加简洁的创建生成器的方式,语法类似列表推导式,使用圆括号而非方括号
# 示例:生成1到10的平方的生成器表达式
square_gen = (i ** 2 for i in range(1, 11))
# 遍历生成器
for num in square_gen:
print(num, end=" ") # 输出: 1 4 9 16 25 36 49 64 81 100
生成器表达式与列表推导式的区别
- 生成器表达式是惰性求职,列表表达式是立即求职
- 生成器表达式不存储所有元素,内存效率更高
- 生成器表达式只能迭代一次,列表可以多次迭代
生成器的高级用法
- 生成器作为协程
-生成器可以接受外部发送的值,通过
send()方法实现,这使得生成器可以作为协程使用。
def echo():
while True:
value = yield
print(f"收到值: {value}")
# 创建协程
coroutine = echo()
next(coroutine) # 启动协程
# 发送值到协程
coroutine.send("Hello") # 输出: 收到值: Hello
coroutine.send("World") # 输出: 收到值: World
- 生成器链 可以将多个生成器连接起来,形成生成器链,实现数据的流水线处理
def numbers():
for i in range(1, 6):
yield i
def squared(gen):
for num in gen:
yield num ** 2
def even_only(gen):
for num in gen:
if num % 2 == 0:
yield num
# 连接生成器
num_gen = numbers()
square_gen = squared(num_gen)
even_gen = even_only(square_gen)
# 遍历结果
for num in even_gen:
print(num) # 输出: 4, 16
生成器的优势
- 内存效率高:无需一次性创建所有数据,适合处理大数据集
- 延迟计算:按需生成数据,提高程序响应速度
- 无限处理:可以生成理论上无限的序列,如随机数生成
- 流式处理:适合处理流式数据,如日志文件,网络数据