Python生成器使用场景2 - 处理无限队列 - 节省cpu 资源

什么是无限队列?

例如常见的斐波那契数列, 自然数队列等
这次我们用素数队列来举个例子



普通方法求素数

首先我用普通的方法编写1个 generate_prime_numbers(n) 的函数, return 1个包含前n个素数的list

def generate_prime_numbers(num=10):
    count = 1
    list_primes = [2]  # 用于存储已发现的素数
    n = 3  # 从3开始检查奇数是否是素数

    while True:
        is_prime = True
        for prime in list_primes:
            if prime * prime > n:
                break
            if n % prime == 0:
                is_prime = False
                break

        if is_prime:
            list_primes.append(n)
            count += 1
            if count >= num:
                break

        n += 2  # 只检查奇数是否是素数

    return list_primes


# get the No.10 prime number
list_primes = generate_prime_numbers(10)
print(list_primes)  # [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
print(list_primes[-1])  # 29

# get the No.11 prime number
list_primes = generate_prime_numbers(11)
print(list_primes[-1])  # 31

但我们想求第10个素数时, 我们用10作为参数 调用了这个函数

# get the No.10 prime number
list_primes = generate_prime_numbers(10)
print(list_primes[-1])  # 29

然后获取返回list 中的最后1个值 就是 第10个素数了

但是当我们再想求第11个时, 如果上次执行的结果没有包含, 则要再运算一次, 注意这次运算是从头开始算的, 相当浪费cpu 资源



利用list 对象保存已经求得的素数

为了解决上面的问题, 我们可以令这个函数接受1另1个参数 已知素数的列表


def generate_prime_numbers(num=10, list_known_primes=[]):
    count = 1
    list_primes = [2]  # 用于存储已发现的素数
    n = 3  # 从3开始检查奇数是否是素数

    if list_known_primes:
        list_primes = list_known_primes
        count = len(list_primes)
        n = list_primes[-1] + 2

    while True:
        is_prime = True
        for prime in list_primes:
            if prime * prime > n:
                break
            if n % prime == 0:
                is_prime = False
                break

        if is_prime:
            list_primes.append(n)
            count += 1
            if count >= num:
                break

        n += 2  # 只检查奇数是否是素数

    return list_primes


# get the No.10 prime number
list_primes = generate_prime_numbers(10)
# print(list_primes)  # [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
print(list_primes[-1])  # 29

# get the No.11 prime number
list_primes = generate_prime_numbers(11, list_primes)
print(list_primes[-1])  # 31

这样修改后, 第二此求第11 个素数时 我可以把前10个素数的列表传入 求前11个素数函数作为参数
这样的确能大大节省cpu资源

但是, 它消耗额外内存
而且不太优雅



使用生成器的例子

def generate_prime_numbers():
    count = 1
    list_primes = [2]  # 用于存储已发现的素数
    n = 3  # 从3开始检查奇数是否是素数
    yield list_primes[-1] # first output 2
    while True:
        
        is_prime = True
        for prime in list_primes:
            if prime * prime > n:
                break
            if n % prime == 0:
                is_prime = False
                break

        if is_prime:
            list_primes.append(n)
            yield list_primes[-1] # from second to last output here
            count += 1

        n += 2  # 只检查奇数是否是素数

    return # raise StopIteration


# get the No.10 prime number [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
list_primes = generate_prime_numbers()
for i in range(1,10): # from 1 to 9
    next(list_primes)

print(next(list_primes))  # 29 the No.10 prime number

print("=============================================")

# get the No.11 prime numbe
print(next(list_primes))  # 31 the No.11 prime number

区别是

  1. 生成素数的函数不需要1个上限个数参数num了 (普通方法需要否则停不下来), 因为它没输出1个素数就会暂停一次
  2. 也不需要把之前的known_prime 保存在另1个地方, 因为他们保存在生成器本身的1个list里 list_prime
  3. 使用的它的方法跟使用迭代器一样
  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nvd11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值