最朴素的方法,对 2到n的每个数i,确认其是否能被从2到sqrt(i)的数整除
N = 10000 def isPrime(n): if n<=1: return False i = 2 while (i*i<=n): if n%i == 0: return False i+=1 return True prime_ls = [] for i in range(2,N): if isPrime(i): prime_ls.append(i)对版本1的改进,排除掉i为偶数的情况
N = 10000 def isPrime(n): if n<=1: return False if n%2 == 0: return False i = 3 while (i*i<=n): if n%i == 0: return False i+=2 return True prime_ls = [2] for i in range(3,N): if isPrime(i): prime_ls.append(i)网上最常见的python素数筛法,利用到了python的特性:生成器
N = 10000 def odd_iter(): n = 1 while(True): n += 2 yield n def not_divisble(n): return lambda x: x%n>0 def primes(): yield 2 it = odd_iter() while(True): n = next(it) yield n it = filter(not_divisble(n),it) prime_ls = [] for i in primes(): if i >= N: break prime_ls.append(i)注:filter中的 not_divisble(n),不能直接替代为 lambda x: x%n>0,原因未知
素数筛法
N = 10000 def get_primes(n): isp = [x%2==1 for x in range(n+1)] isp[1] = False isp[2]= True p = [2] for i in range(3,n+1,2): if(isp[i]): p.append(i) for j in p: if(i*j<=n): isp[i*j] = False else: break if(i%j == 0): break return p prime_ls = get_primes(N)表格中的数据为使用对应版本的算法,求小于N的所有素数所花时间的 m e a n ± s t d mean\pm std mean±std
方法N=1000N=5000N=10000N=50000版本1 604 µ s ± 62.9 µ s 604 µs ± 62.9 µs 604µs±62.9µs 6.23 m s ± 2.24 m s 6.23 ms ± 2.24 ms 6.23ms±2.24ms 11.8 m s ± 778 µ s 11.8 ms ± 778 µs 11.8ms±778µs 108 m s ± 8.47 m s 108 ms ± 8.47 ms 108ms±8.47ms版本2 378 µ s ± 49.2 µ s 378 µs ± 49.2 µs 378µs±49.2µs 2.75 m s ± 230 µ s 2.75 ms ± 230 µs 2.75ms±230µs 6.5 m s ± 276 µ s 6.5 ms ± 276 µs 6.5ms±276µs 59.3 m s ± 9.29 m s 59.3 ms ± 9.29 ms 59.3ms±9.29ms版本3 1.64 m s ± 165 µ s 1.64 ms ± 165 µs 1.64ms±165µs 23.3 m s ± 1.46 m s 23.3 ms ± 1.46 ms 23.3ms±1.46ms 81.8 m s ± 7 m s 81.8 ms ± 7 ms 81.8ms±7ms 1.4 s ± 66.6 m s 1.4 s ± 66.6 ms 1.4s±66.6ms版本4 224 µ s ± 64.6 µ s 224 µs ± 64.6 µs 224µs±64.6µs 1.03 m s ± 37.6 µ s 1.03 ms ± 37.6 µs 1.03ms±37.6µs 2.07 m s ± 100 µ s 2.07 ms ± 100 µs 2.07ms±100µs 11 m s ± 467 µ s 11 ms ± 467 µs 11ms±467µs