Python 生成器是处理数据序列的一种强大而有效的方法。它们允许惰性求值,这意味着仅根据需要即时生成值,这可以显着提高性能并节省内存,特别是在处理大型数据集时。
1. 生成器简介生成器提供了一种在 Python 中实现迭代器的便捷方法。迭代器是代表数据流的对象;它实现了 __iter__() 和 __next__() 方法。生成器通过提供一种一次生成一个值的简洁方法来简化迭代器的创建。
2. 生成器如何工作生成器是一种可迭代的类型,就像列表或元组一样。然而,与列表不同,生成器不会将其内容存储在内存中。相反,它们会即时计算每个值并在需要时生成它。这种惰性评估模型使生成器具有很高的内存效率。
3. 创建生成器生成器函数使用 def 关键字定义,就像普通函数一样,但它不是使用 return 返回值,而是使用 yield 关键字。每次调用生成器的 __next__() 方法时,该函数都会从最后一个 yield 语句恢复执行,并保留调用之间的状态。
def count_up_to(max): count = 1 while count <= max: yield count count += 1counter = count_up_to(5)for number in counter: print(number)输出:
12345生成器表达式生成器表达式与列表推导式类似,但使用括号而不是方括号。它们提供了一种创建生成器的紧凑方法。
numbers = (x**2 for x in range(10))for num in numbers: print(num)输出:
01491625364964814. 使用生成器可以使用 for 循环或其他迭代工具来迭代生成器。
def fibonacci(limit): a, b = 0, 1 while a < limit: yield a a, b = b, a + bfib = fibonacci(10)for num in fib: print(num)输出:
0112358next() 函数
可以使用 next() 函数从生成器手动检索值。
def simple_gen(): yield 1 yield 2 yield 3gen = simple_gen()print(next(gen)) # Output: 1print(next(gen)) # Output: 2print(next(gen)) # Output: 3StopIteration 异常
当生成器没有更多值可生成时,它会引发 StopIteration 异常。这是在 for 循环中自动处理的,但也可以手动捕获。
gen = simple_gen()try: while True: print(next(gen))except StopIteration: print("No more items.")输出:
123No more items.5. 发电机特点
无限序列
生成器可以生成无限序列,因为它们动态生成值并且不将它们存储在内存中。
例子:
def infinite_sequence(): num = 0 while True: yield num num += 1inf_seq = infinite_sequence()for i in range(5): print(next(inf_seq))输出:
01234状态保留生成器在生成之间保留其状态,这使得它们对于需要有状态迭代的任务非常有用。
例子:
def cumulative_sum(): total = 0 while True: num = yield total if num is None: break total += numcumsum = cumulative_sum()print(next(cumsum)) # Initialize the generator, output: 0print(cumsum.send(10)) # Output: 10print(cumsum.send(20)) # Output: 30print(cumsum.send(30)) # Output: 606. 性能优势生成器在处理大型数据集或数据流时特别有用,因为它们不需要将整个数据集加载到内存中。这可以显着提高性能。
例子:
def read_large_file(file_path): with open(file_path, 'r') as file: for line in file: yield line.strip()file_gen = read_large_file('large_file.txt')for line in file_gen: process(line) # Some function to process the line7. 实例文件读取
生成器对于逐行读取大文件很有用。
例子:
def read_file(file_path): with open(file_path) as file: for line in file: yield line.strip()for line in read_file('large_file.txt'): print(line)流处理
可以使用生成器有效地处理流中的数据。
例子:
import randomdef data_stream(): while True: yield random.randint(0, 100)stream = data_stream()for _ in range(10): print(next(stream))管道
生成器可以链接在一起形成数据处理管道。
例子:
def generate_numbers(): for i in range(10): yield idef square_numbers(numbers): for number in numbers: yield number ** 2def print_numbers(numbers): for number in numbers: print(number)print_numbers(square_numbers(generate_numbers()))输出:
0149162536496481