Python 惰性求值

  • Post category:Python

Python中的惰性求值指的是延迟计算,即只有在真正需要结果的时候才会进行计算,这样可以避免不必要的计算浪费,提高程序效率。

实现惰性求值的方式主要有两种,一种是使用生成器(generator),另一种是使用迭代器(iterator)。下面分别介绍这两种方式的使用方法。

生成器实现惰性求值

生成器是一种特殊的迭代器,它可以在迭代的过程中生成值,而不是在一开始就生成所有的值。通过生成器实现惰性求值可以大大节省内存空间,因为只有在需要使用该值时才会生成。

示例1:斐波那契数列生成器

def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

使用生成器实现斐波那契数列,在迭代过程中每次只生成下一个数,而不是在一开始就生成所有的数。这样可以实现惰性求值,只有在需要用到某个数的时候才会生成。

f = fibonacci()
for i in range(10):
    print(next(f))

输出结果为:

0
1
1
2
3
5
8
13
21
34

示例2:筛选质数生成器

def prime_numbers():
    yield 2
    primes = [2]
    candidate = 3
    while True:
        is_prime = True
        for p in primes:
            if candidate % p == 0:
                is_prime = False
                break
        if is_prime:
            primes.append(candidate)
            yield candidate
        candidate += 2

使用生成器实现筛选质数,通过迭代的方式生成所有质数。由于只有在需要用到某个数的时候才会生成,因此可以实现惰性求值。

p = prime_numbers()
for i in range(10):
    print(next(p))

输出结果为:

2
3
5
7
11
13
17
19
23
29

迭代器实现惰性求值

迭代器是一种可以用于遍历容器类对象(比如列表、元组、字典等)的对象。通过迭代器实现惰性求值可以避免一次性读入所有元素造成内存浪费。

示例1:文件读取迭代器

def file_lines(filename):
    with open(filename, 'r') as f:
        for line in f:
            yield line.rstrip('\n')

使用迭代器实现惰性读取文件的每一行内容,避免一次性读入文件所有内容造成内存浪费。

f = file_lines('example.txt')
for i in range(3):
    print(next(f))

输出结果为:

This is an example file.
It contains three lines.
Each line has some text.

示例2:字典生成器

def dict_items(d):
    for k in d:
        yield (k, d[k])

使用迭代器实现惰性读取字典的每一项内容,而不是把所有的键值对一次性读入内存。

d = {'a': 1, 'b': 2, 'c': 3}
for k, v in dict_items(d):
    print(k, v)

输出结果为:

a 1
b 2
c 3