yield是Python中的关键字,用于在函数中返回生成器。
当函数被调用时,yield会返回一个值,并保存当前函数状态。
下次迭代时,函数会从保存的状态继续执行,而非从头开始。
yield常用于处理大数据集或需要保持内存使用高效的场景。
例如,创建一个简单的生成器函数:
def count_up_to(n):
for i in range(n):
yield i
# 使用生成器
for num in count_up_to(5):
print(num)
此函数会依次返回0到n-1的值。
跟普通的 return 不同的是,yield 会返回一个值,并且保存当前函数的状态,以便下次迭代时从此状态继续执行。这在处理大数据集或需要保持内存使用高效的场景中特别有用。
def simple_generator():
yield 1
yield 2
yield 3
# 使用生成器
gen = simple_generator()
for value in gen:
print(value)
这个生成器函数会依次返回 1、2 和 3,并且在每次 yield 之后都会暂停,直到被再次调用。
再看一个稍微复杂一点的例子,用 yield 来生成斐波那契数列:
def fibonacci_sequence():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
# 使用生成器
fib = fibonacci_sequence()
for _ in range(10):
print(next(fib))
在这个例子中,fibonacci_sequence 是一个无限生成斐波那契数列的生成器。利用 yield,我们可以在不占用大量内存的情况下获取数列中的任意多个元素。
讲解:先明确代码行号
1. def fibonacci_sequence():
2. a, b = 0, 1
3. while True:
4. yield a
5. a, b = b, a + b
7. 使用生成器
8. fib = fibonacci_sequence()
10. for _ in range(10):
11. print(next(fib))
下面逐次追踪,每次next(fib)对应1次循环,明确执行的行号:
第1次循环(_=0,执行print(next(fib)))
• 首次调用next(fib),进入生成器函数(第1行)
• 执行第2行:a, b = 0, 1(a=0,b=1)
• 执行第3行:while True(条件成立,进入循环体)
• 执行第4行:yield a(产出0,打印结果第1个是0),生成器暂停(停在第4行)
• 本次执行行号:1→2→3→4
第2次循环(_=1,执行print(next(fib)))
• 恢复生成器(从第4行暂停处继续)
• 执行第5行:a, b = b, a + b(旧a=0、旧b=1,计算后a=1,b=1)
• 执行第3行:while True(条件成立)
• 执行第4行:yield a(产出1,打印结果第2个是1),生成器暂停(停在第4行)
• 本次执行行号:5→3→4
第3次循环(_=2,执行print(next(fib)))
• 恢复生成器,执行第5行:a, b = b, a + b(旧a=1、旧b=1,a=1,b=2)
• 执行第3行:while True(成立)
• 执行第4行:yield a(产出1,打印结果第3个是1),暂停
• 本次执行行号:5→3→4
第4~10次循环(规律完全相同)
每一次都是重复:恢复生成器→执行第5行(更新a、b)→执行第3行(循环条件成立)→执行第4行(yield产出值,暂停)
• 第4次:执行5→3→4,产出2(打印第4个值)
• 第5次:执行5→3→4,产出3(打印第5个值)
• 第6次:执行5→3→4,产出5(打印第6个值)
• 第7次:执行5→3→4,产出8(打印第7个值)
• 第8次:执行5→3→4,产出13(打印第8个值)
• 第9次:执行5→3→4,产出21(打印第9个值)
• 第10次:执行5→3→4,产出34(打印第10个值)
关键总结
• 只有第1次调用next(fib)时会执行第2行(初始化a、b),之后再也不执行第2行
• 从第2次到第10次,每次仅执行3行:第5行(更新a、b)→第3行(循环判断)→第4行(产出值)
• 生成器永远停在第4行,每次next()都是从第5行开始恢复执行
1236

被折叠的 条评论
为什么被折叠?



