2017-09-11 69 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为止的每一个数字,而不是从我寻找素数的范围开始数字。 –