2024-01-07 00:34:56
yield 关键字用于定义生成器函数,调用生成器函数会返回一个生成器对象,该对象是一个迭代器,可通过 next() 逐个获取值。
生成器与列表推导式的区别列表推导式(如 a = [i*i for i in range(3)])会直接生成完整列表并存储在内存中,而生成器表达式(如 (i*i for i in range(3)))或含 yield 的函数会返回生成器对象,世渣按需动态生成值,节省内存。
生成器的工作原理当函数包含 yield 时,它成为生成器函数。调用时返回生成器对象,但函数体不会立即执行。每次调用 next() 时,函数执行到 yield 处暂停并返回值,下次调用从暂停处继续。
示例代码解析
def generator(): for i in range(3): yield i*ig = generator()print(g) # 输出生成器对象地址print(g.next()) # 输出 0(第一次 yield 的值)首次 next() 触发函搜老悄数执行到 yield 0,返回 0 并暂停。
后续 next() 会继续执行循环,直到函数结束或无更多 yield,此时抛出 StopIteration。
生成器作为迭代器的特性生成器对象实现了迭代器协议(__iter__() 和 __next__()),可直接用于循环或手动调用 next()。生成完毕后再次调用 next() 会抛出 StopIteration,需重新创建生成器对象。
控制生成器终止通过外部标志(如 flag)可动态控制生成器的执行。例如:
class Generator: flag = False def creategenerator(self): while not self.flag: yield "value"g = Generator()gen = g.creategenerator()print(gen.next()) # 输出 "value"g.flag = Trueprint(gen.next()) # 抛出 StopIteration自定义迭代器 vs 生成器自定义迭代器含迅需实现 __iter__() 和 next()(Python 3 中为 __next__()),而生成器通过 yield 自动处理迭代逻辑,代码更简洁。例如:
class Squares: def __init__(self, start, stop): self.start = start self.stop = stop def __iter__(self): return self def __next__(self): if self.start >= self.stop: raise StopIteration current = self.start 2 self.start += 1 return current等价生成器版本:
def squares(start, stop): while start < stop: yield start 2 start += 1生成器的应用场景
处理大规模数据流(避免内存溢出)。
实现惰性计算(按需生成值)。
简化协程或异步编程(如 yield from 语法)。
总结:yield 将函数转换为生成器,生成器是高效的迭代器实现方式,适合处理潜在无限序列或大数据集,同时支持通过外部控制动态调整生成逻辑。