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

上記のコードはシェルで動作します。

私の質問は次のとおりです:私は解決策ではあるが、それは最もエレガントなものではないように感じるので、誰でもこのコードをよりPythonのようなものに変換できますか?(より良い構造?より少ない行?)

言語の基礎をよりよく理解するのに役立つと思います。

問題は、インポートなどを使用しないでください。単純なスタッフだけです。

4

4 に答える 4

4

リストのコピーを多数作成することは、特に効率的な方法ではありません。代わりにxrange()(Python 2.x) またはrange()(Python 3) イテレータを使用してください。素数性テストを実装できる (単純な) 方法の 1 つを次に示します。

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。すべての False 数のシーケンスを生成すると、素数があることがわかります。

次のトリックはany組み込み関数です。基本的に iterable を検索し、いずれかの値が True かどうかをチェックします。にヒットするとすぐにTrueTrue を返します。iterable の最後まで到達すると、 を返します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 に答える