2017-09-11 111 views
1

這不是關於查找素數的問題,而是關於如何將代碼轉換爲函數。Python函數查找素數

所以我有這樣的代碼,以幫助我從2-100打印素數:

pnumber = [x for x in range(2, 101) if all(x % i for i in range(2, x))] 
print(pnumber) 

如果我這個變形點焊的功能,尋找素數範圍:

def p_number(a, b): 
    pnumber = [x for x in range(a, b+1) if all(x % i for i in range(2, b))] 
    print(pnumber) 

p_number(2, 100) 

您可以看到我使用a代替2,b代替100,並相應地更改代碼。但不知何故,這不起作用,它會輸出一個空的列表。

我想知道爲什麼?

+1

那麼這是合乎邏輯的:因爲質數也在'範圍(2,b)'中。所以如果你測試'3',它會導致'3%3 == 0',因此'all(..)'將會失敗... –

+0

'返回(pnumber)'更改'print(pnumber)' –

+5

爲什麼'range(2,x)'變成'range(2,b)'? – asongtoruin

回答

2

記住,如果你在支票使用上界b

all(x % i for i in range(2, b)) 

這將包括所有素數達b。所以2,3,5等也是range(2, b)的一部分(給出的b足夠大)。這意味着如果我們測試3是否爲素數,我們將檢查i = 33 % 30,這樣就會失敗。

此外,它會對性能造成不良影響。主要測試的想法是檢查所有數字,但是不包括的數字。所以速戰速決是:

def p_number(a, b): 
    pnumber = [x for x in range(a, b+1) if all(x % i for i in range(2, x))] 
    print(pnumber)

我們可以很容易地提高其進一步使用int(sqrt(x))+1代替x

from math import sqrt 

def p_number(a, b): 
    pnumber = [x for x in range(a, b+1) if all(x % i for i in range(2, int(sqrt(x))+1))] 
    print(pnumber)

我們只能由評估奇數進一步推動它,例如(加入2到結果)。但使用sqrt通常會導致顯着的加速。

+0

我明白了!如果我把p_number(2,100): 當我檢查每個x時,例如x = 11,它仍然會迭代2-100的所有i,當然這會包括11,然後排除11作爲素數。但是,如果我使用i的範圍(2,x),那麼對於每個x,我的範圍將有一個範圍

+0

如果ALL找到N達到N,那麼除了sqrt限制:僅在已經發現的素數之前進行測試。 – VPfB

2

的功能更改爲 -

def p_number(a, b): 
    pnumber = [x for x in range(a, b + 1) if all(x % i for i in range(a, x))] 
    print(pnumber) 

如果你發現,你是從2迭代到B,而不是從2至x這就是爲什麼你得到一個空列表。

+0

我明白了,我的範圍是錯誤的。但我認爲你不應該在這裏使用我的範圍作爲(a,x),因爲我仍然想要從2開始到b-1爲止的每一個數字,而不是從我尋找素數的範圍開始數字。 –