这里主要是要考虑效率问题,在数据规模较大时,若是不考虑算法优化,效率将会很是差。html
import time # 将特殊质数2事先放在列表中 t = [2] t0 = time.time() count = 1 # 去掉全部偶数,从3开始迭代,步进为2 for x in range(3, 100000, 2): # 全部大于10的质数中,个位数只有一、三、七、9,大于5且以5结尾的整数能被5整除,这里首先过滤掉大于5且以5结尾的整数 if x > 5 and x % 10 == 5: continue # 除去2以外,质数的因子中确定是没有2的,这里去掉全部被除数中的偶数 # 一个整数的先后对应的两个因子的乘积等于这个整数,因此一个整数若是平方根以前有一个因子,那平方根以后确定有一个对应的因子,中间是平方根 # 这里使用平方根极大减少了数据规模,以及减小了大量迭代次数 for i in range(3, int(x ** 0.5) + 1, 2): if x % i == 0: break # 要格外注意一下这里的else语句的执行逻辑 # 没有进入for循环、以及for循环正常结束都会执行else语句,若是被break中断,else不会执行 else: count += 1 t.append(x) # print(t) print('花费时间: {}'.format(time.time() - t0)) print('质数个数: {}'.format(count)) print('质数个数: {}'.format(len(t))) # 花费时间: 0.20165777206420898 # 质数个数: 9592 # 质数个数: 9592
为何能够只考虑平方根以前的部分,上面的备注中已经作了说明,这里以100为例解剖一下:python
for i in range(2, 100): if not 100 % i: print(i) 2 4 5 10 20 25 50 100 = 2 x 50 100 = 4 x 25 100 = 5 x 20 100 = 10 x 10 这样很容易看出,在平方根10以前,若是100有一个因子,那么平方根后面必定有一个对应的因子,而平方根`10x10`是临界点。因此被除数能够从平方根处砍掉后面的部分。 因为相差一个指数,一个整数的平方根一般都比自身小不少,数值越大,相差越大。好比100比10大90,10000比100大9900,这样看就发现数据量减小了不止一星半点。
关于for循环中else语句的执行逻辑,简单敲一下就清晰了:算法
# 没有进入for循环会执行else语句 for i in range(3,2): print('a') else: print('b') # b # for循环正常结束会执行else语句 for i in range(3,4): print('a') else: print('b') # a # b # for循环若是被break中断,else语句不会执行 for i in range(3,5): print('a') break else: print('b') # a
参考:
https://docs.python.org/3/reference/compound_stmts.html#the-for-statement
http://www.javashuo.com/article/p-sldlphrt-cy.htmlapp