2012-07-14 80 views
0

我今天从官方网站上的教程开始学习python。如何编写更多Pythonic代码

当阅读约过滤器(功能,序列)我想做一个函数,如果一个数字是素数,返回与过滤器一起使用它。

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中工作。

我的问题是:因为我觉得虽然一个解决方案,它是不是最优雅的一个,任何人都可以将这些代码的东西更蟒蛇般

相信?(更好的结构不太行?)它会帮助我更好地理解语言的基础知识。

事情是,不要使用任何进口或任何东西,只是简单的工作人员。

+0

检查出这个Python的部分,也为一些好的想法http://rosettacode.org/wiki/Sieve_of_Eratosthenes#Functional – dfb 2012-07-14 00:47:11

回答

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 
+0

x范围,甚至更好,因为它是一个生成 – GoingTharn 2012-07-14 00:41:12

+0

@GoingTharn:在Python 3。 x,'range()'是一个生成器,'xrange()'不再存在。 – 2012-07-14 00:43:54

+0

我选择了这个答案,因为它是最接近我正在寻找。谢谢 – Blm33 2012-07-14 00:58:53

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 
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则为真,否则为False。如果我们生成一个所有虚数的序列,我们知道我们有一个素数。

下一个技巧是内置函数any。它基本上通过迭代器进行搜索,并检查是否有任何值为True。只要它遇到True,它就会返回True。如果它到达可迭代的末尾,则返回False。所以,如果整个序列是False(一个素数),那么any将返回False,否则返回True。这对于not_prime函数是完美的,但是我们的函数是is_prime,所以我们只需要使用not运算符来反转结果。

使用生成器表达式的好处是它很好,简洁,但它也允许any在检查每个值之前返回,这意味着只要它找到一个除数num的数字,它就返回而不是生成全部为num/2号码。

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

+0

+1进行评论之前进行了检查;但也许你应该考虑OP是一个新手,所以你可能应该详细阐述/解释更多! ;-) – 2012-07-14 00:51:23

+2

@DonQuestion - 你说得对。我添加了一个解释,但我担心我们已经失去了这个答案的简洁性(尽管代码仍然简短:) – mgilson 2012-07-14 01:17:16

0

这是一个使用过滤器(2)的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