4

私は本当にPythonの初心者なので、知識がなくて申し訳ありませんが、Pythonのマニュアルとチュートリアル(http://docs.python.org/2.7/tutorial)を読んでいるからです。ループがどのように機能するかを完全に把握することはできません。私はいくつかの簡単なプログラムを書いたので、基本は理解できたと思いますが、何らかの理由で、n 以下のすべての素数をリストすることを意図したこのプログラムは機能しません。

n = int(raw_input("What number should I go up to? "))
p = 2
while p <= n:
        for i in range(2, p):
                if p%i == 0:
                        p=p+1 
        print "%s" % p,
        p=p+1
print "Done"

たとえば、100 を入力したときの出力は次のとおりです。

2 3 5 7 11 13 17 19 23 27 29 31 35 37 41 43 47 53 59 61 67 71 73 79 83 87 89 95 97 101 Done

これはほぼ正しいように見えますが、何らかの理由で 27、35、95 が含まれており、これらはもちろん複合です。私は自分のループが機能する方法を分解しようとしていますが、分割可能性のチェックを突然スキップする場所がわかりません。誰かが見れば、構文がこれを引き起こしていることを説明できると思いました。本当にありがとう!

4

14 に答える 14

17

実際にプログラムを次のように再構築します。

for p in range(2, n+1):
    for i in range(2, p):
        if p % i == 0:
            break
    else:
        print p,
print 'Done'

これはおそらくより慣用的な解決策 (forループの代わりにループを使用while) であり、完全に機能します。

外側のforループは、2 から までのすべての数値を反復処理しますn

内側のものは 2 から までのすべての数値を反復しますp。に均等に分割される数に達するpと、内側のループから抜け出します。

ブロックはelsefor ループが抜け出さない (素数を出力する) たびに実行されます。

その後、プログラムは終了後に印刷'Done'されます。

p補足として、各因子にはペアがあるため、2 から の平方根まで反復するだけで済みます。一致しない場合、平方根の後に他の要因はなく、数は素数になります。

于 2013-02-01T23:23:12.107 に答える
6

コードには 2 つのループがあり、1 つは別のループです。内側のループを関数に置き換えると、コードを理解するのに役立ちます。次に、関数が正しく、(外側のループから分離して) 自立できることを確認します。

これがあなたの元のコードの私の書き直しです。この書き直しは完全に機能します。

def is_prime(n):
    i = 2
    while i < n:
        if n%i == 0:
            return False
        i += 1
    return True


n = int(raw_input("What number should I go up to? "))

p = 2
while p <= n:
    if is_prime(p):
        print p,
    p=p+1

print "Done"

is_prime()外側のループのループ インデックスには触れないことに注意してください。これはスタンドアロンの純粋関数です。p内側のループ内のインクリメントが問題でしたが、この分解されたバージョンには問題がありません。

これで、ループを使用して簡単に書き直すことができfor、コードが改善されたと思います。

def is_prime(n):
    for i in range(2, n):
        if n%i == 0:
            return False
    return True


n = int(raw_input("What number should I go up to? "))

for p in range(2, n+1):
    if is_prime(p):
        print p,

print "Done"

Python では、range()に渡す上限が決して含まれないことに注意してください。したがって、 をチェックする内側のループ< nは単純に呼び出すことができますrange(2, n)が、 が必要な外側のループについては、<= nに 1 を追加してn、それnが含まれるようにする必要があります。range(2, n+1)

Python には、楽しい機能が組み込まれています。これらすべてのトリックをすぐに習得する必要はありませんが、別の書き方を次に示しますis_prime()

def is_prime(n):
    return not any(n%i == 0 for i in range(2, n))

これは、 のforループ バージョンと同じように機能しますis_prime()i値を設定してrange(2, n)それぞれをチェックし、テストが失敗した場合はチェックを停止して戻ります。n範囲内のすべての数値をチェックし、どの数値も均等に分割されない場合n、その数値は素数です。

繰り返しますが、これらすべてのトリックをすぐに習得する必要はありませんが、習得すると楽しいと思います。

于 2013-02-01T23:45:42.150 に答える
2

これはうまくいくはずで、もう少し最適化されています

import math
for i in range(2, 99):
  is_prime = True
  for j in range(2, int(math.sqrt(i)+1)):
    if i % j == 0:
      is_prime = False
  if is_prime:
    print(i)
于 2016-01-18T20:33:54.680 に答える
1

i非素数を見つけた後、ループを再開しません

p = i = 2
while p <= n:
    i = 2
    while i < p:
        if p%i == 0:
            p += 1 
            i = 1
        i += 1

    print p,
    p += 1

print "Done"

whileループは本体を実行し、上部の条件が であるかどうかを確認し、真Trueの場合は本体を再度実行します。ループは、イテレータ内のforアイテムごとに本体を 1 回実行します。

于 2013-02-01T23:00:52.377 に答える
1

スニペットを下に貼り付けたものと比較すると、どこが間違っているかがわかります。

n = int(raw_input("What number should I go up to? "))
p = 2
while p <= n:
    is_prime=True
    for i in range(2, p):
        if p%i == 0:
            is_prime=False
            break;
    if is_prime==True:
        print "%d is a Prime Number\n" % p
    p=p+1
于 2013-02-01T23:17:19.920 に答える
0
for i in range(2, p):
    if p%i == 0:
        p=p+1 
     print "%s" % p,
     p=p+1

私はあなたのエラーのみを伝えるつもりです.3行目であなたはpを増やしていますが、実際に欠けているのはあなたのiです.前のケースであなたのiが13と言われた場合、13の後にループをチェックしますが、2,3を離れています. ,5,7,11 なので、エラーです。27 の場合、27 の前の i が 13 で、14 からチェックされます。解決策は必要ないと思います。

于 2014-08-05T08:27:27.513 に答える