2010-12-02 15 views
1

thisメソッドを使用して素数のリストを生成しようとしています。私はすべての番号2 ... nをループし、2 ... nの倍数をチェックする必要があります。何らかの理由で間違ったリストが変更されているようです。間違ったリストを修正するPython?

import sys 
import argparse 
import math 

parser = argparse.ArgumentParser(description='find the largest prime factor of a number') 
parser.add_argument('n', type=int, help='number') 
args = parser.parse_args() 

sieve = [] 
for i in range(2,args.n+1): sieve.append(i) # tried int(i) 


copy1 = sieve # tried making extra copies. . . 
copy2 = sieve 
copy3 = sieve 
#print int(math.sqrt(args.n)) 

for index, i in enumerate(copy1): 
    #print index, i 
    for ii in copy2: 
     #print ii 
     if i % ii == 0: 
      sieve[index]= None 


print sieve 

私は次のエラーを取得する:

Traceback (most recent call last): 
    File "3.py", line 22, in <module> 
    if i % ii == 0: TypeError: unsupported operand type(s) for %: 
'int' and 'str' 

答えて

7

あなたはコピーを行っていません。参照を使用しているので、copy1copy2、およびcopy3はすべて同じリスト - sieveを参照しています。コピーしたい場合は、使用します。

sieveのコピーを作成し、 copy1に割り当てます
copy1 = sieve[:] 

+4

この混乱は非常に一般的です...言語上のすべての素材(同様の意味論を持つすべての言語で、btw)は、次のようにして実装できます。これを要約した巨大な赤いボックスが入っているはずです。 – delnan

+2

delnan:また、浮動小数点演算の仕組みを説明するものもあります。 :-) – Ken

+0

java String == Stringはあなたがしたいことではありません。 – Falmarri

2

あなたが実際にリストをコピーする

copy1 = sieve[:] # tried making extra copies. . . 
copy2 = sieve[:] 
copy3 = sieve[:] 

を使用する必要があります。それ以外の場合は、参照をリストにコピーするだけです。

>>> a = [1,2] 
>>> b = a 
>>> c = a[:] 
>>> b[0] = 0 
>>> c[0] = 3 
>>> a 
[0, 2] 
>>> b 
[0, 2] 
>>> c 
[3, 2] 
2
copy1 = sieve 
copy2 = sieve 
copy3 = sieve 

これらは、参照のあるコピーではありません。

primes = [2,3,5,7] 

def is_prime(n): 
    if n in primes: 
     return True 
    for item in primes: 
     if n % item == 0: 
      return False 
    return True 

assert is_prime(4) == False 
assert is_prime(29) == True 
assert is_prime(65) == False 

私は、Python 3.2のコピーを持っていないので、私は、これをテストすることができませんでした

true_primes = [int(item) for item in '11,13,17,19,23,29,31,37,41,43,47'.split(',')] 
for item in xrange(10, 50): 
    if is_prime(item) == True: 
     assert item in true_primes 
    else: 
     assert item not in true_primes 
1

その楽しいので、良いふるい法

より、ユニットテストです(​​されますPython 3.2の新機能)しかし、2つの明白なことが思い浮かぶ:

まず、sieve.append(int(i))を実行する必要があります。

第2に、あなたはsieveのコピーを作成していないので、単に同じリストへの新しい参照を作成するだけです。コピーを作成するには、

copy1 = sieve[:] 
2

を参照する必要があります。一般に、a = bは、名前の名前が現在参照しているのと同じ値を参照するように、名前aを指定します。新しい値を作成または保存することはありません。

上記の[:]トリックでリストをクローンできます。物事をコピーするためのより汎用的なソリューションは、copyモジュールを使用することです。

しかし、良いPythonコードでは、通常、明示的に物事を頻繁にコピーする必要はありません。リスト内包表記を使用して既存のシーケンスの「変更されたバージョン」を作成することに慣れておく必要があります。

+0

Python 3.xで作業していることが私の注目を集めています。その場合、 'range'は実際に' xrange'がPython 2.xにあったものです。これを解決するために、ジェネレータを明示的にリストする 'sieve = list(range(2、args.n + 1))'のようなことを行うだけです。 –

関連する問題