1

今天从官网的教程开始学习python。

在阅读有关filter(function, sequence)的内容时,我想到了创建一个函数,如果数字是素数,则返回该函数以将其与过滤器一起使用。

notDividedBy = [2,3,4,5,6,7,8,9]

def prime(num):
    """True if num is prime, false otherwise"""    
    copy = notDividedBy[:]
    check = True
    if num in copy:
        copy.remove(num)
    for x in copy:
        if num % x == 0:
            check = False
            break
    return check

上面的代码在 shell 中工作。

我的问题是:因为我觉得虽然是一个解决方案,但它不是最优雅的解决方案,任何人都可以将此代码转换为更像 python 的东西吗?(更好的结构?更少的行?)

我相信这将有助于我更好地理解该语言的基础知识。

问题是,不要使用任何进口或任何东西,只需简单的员工。

4

4 回答 4

4

创建许多列表的副本并不是一种特别有效的做事方式。而是使用xrange()(Python 2.x) 或range()(Python 3) 迭代器。这是您可以实现素性测试的一种(天真的)方法:

from math import sqrt

def isPrime(n):
    if n < 2: return False
    if n == 2: return True
    if not n % 2: return False #test if n is even

    #we've already remove all the even numbers, no need to test for 2
    #we only need to test up to sqrt(n), because any composite numbers can be
    #   factored into 2 values, at least one of which is < sqrt(n)
    for i in xrange(3, int(sqrt(n)) + 1, 2): 
        if not n % i:
            return False
    return True
于 2012-07-14T00:38:46.707 回答
4

这个怎么样:

def is_prime(num):
    return not any(num%i == 0 for i in xrange(2,num/2+1))

for i in xrange(10):
    print i, is_prime(i)

解释

从...开始:

(num%i==0 for i in xrange(2,num/2+1))

这是一个生成器表达式。我可以把它变成一个列表理解:

[num%i==0 for i in xrange(2,num/2+1)]

列表推导等效于:

ll=[]
for i in xrange(2,num/2+1):
    ll.append(num%i==0)

生成器和列表推导之间的区别在于,生成器仅在您对其进行迭代时放弃它的元素——而列表推导会预先计算所有值。不管怎样,从上面的代码中,你可以看到表达式生成了一个 True 和 False 的序列。如果数字可以除以 i,则为 True,否则为 False。如果我们生成一个所有假数的序列,我们就知道我们有一个素数。

下一个技巧是any内置函数。它基本上搜索一个可迭代对象并检查任何值是否为真。一旦它击中 a True,它就会返回 True。如果它到达可迭代的末尾,则返回False. 因此,如果整个序列为 False(素数),则any返回False,否则返回True。这对于not_prime函数来说是完美的,但我们的函数是is_prime,所以我们只需要使用not运算符反转该结果。

使用生成器表达式的好处是它简洁明了,而且它允许any在检查每个值之前返回,这意味着一旦找到一个除以的数字num,它就会返回而不是生成所有num/2数字。

无论如何,我希望这个解释是有帮助的。如果没有,请随时发表评论,我会尽力解释得更好。

于 2012-07-14T00:41:14.677 回答
0

一件事,如果您要以这种方式实施主要测试,没有理由使用辅助阵列

def prime(num):
    """True if num is prime, false otherwise"""    
    check = True
    #if num in copy:
    #    copy.remove(num)
    for x in range(2,x-1):
        if num % x == 0:
            check = False
            break
    return check
于 2012-07-14T00:39:35.293 回答
0

这是使用 filter() 的 2 衬里。

def prime(num):
    """True if num is prime, false otherwise"""
    if num < 2:
        return False
    return len(filter(lambda x: num % x == 0, range(2, num))) == 0
于 2016-08-26T05:13:14.603 回答