這裏主要是要考慮效率問題,在數據規模較大時,若是不考慮算法優化,效率將會很是差。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