作为一个较大程序的一部分,我需要大量迭代低谷质数,因此我制作了一个生成器类,该类在无限循环中吐出质数。
这是课程(代码后有一些解释):
from isqrt import isqrt
from itertools import islice
class prime_generator:
some_prime_numbers = {2, 3, 5, 7, 11}
def __init__(self):
self.primes = sorted(prime_generator.some_prime_numbers)
def __iter__(self):
for i in self.primes: yield i
while True:
check, i = isqrt(i+2), i+2
for j in islice(self.primes, 1, None):
if i % j is 0: break
elif j > check:
prime_generator.some_prime_numbers.add(i)
self.primes.append(i)
yield i
break
isqrt
给出数字的整数平方根。
因为生成器多次运行,所以我使用类变量some_prime_numbers
来记住所有已经计算出的素数,因此我不会一遍又一遍地计算相同的数。我将其设置为一种避免并行处理的方法,该方法给我带来奇怪的结果(数组最终看起来像11、13、17、11、13、17、23 ...),并不断检查数组是否在递增订单似乎太麻烦了。因此,在创建实例时,我只是将集合排序到一个实例列表变量中,然后将其添加到集合中就不会更改集合。
对该程序而言,并行处理确实非常重要,因此我需要考虑到该记忆可能做得很奇怪,但这是我想到的最好的方法(欢迎提出建议)。
我想出了只检查所有奇数(因此i+2
和islice(self.primes, 1, None)
)的原因,所以我根本不必检查2的除数。
process_time()
产生小于1,000,000(在记忆化之前)的所有素数的平均值为7.3259158466,这似乎可以改进。我正在寻找有关如何使生成器更高效的想法。