2012-07-14 69 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