Вопрос

Я пытаюсь создать список простых чисел, используя это метод. Мне нужно верить каждый номер 2 ... n и проверять его для кратных 2 ... n. По какой-то причине неверный список, похоже, становится измененным.

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'
Это было полезно?

Решение

Вы не делаете копии. Вы используете ссылки, так copy1, copy2, а также copy3 Все относятся к одному и тому же списку - sieve. Отказ Если вы хотите скопировать, использовать:

copy1 = sieve[:]

который создаст копию sieve и назначить его copy1.

Другие советы

Вам нужно использовать

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]
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

Это хороший метод сита

Больше единицы тестирования, потому что его веселье

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

Python имеет ссылочную семантику. В основном, a = b вызывает имя a обратиться к тому же значению, что имя b в настоящее время относится к. Он не создает и не хранит новое значение.

Вы можете клонировать список с помощью [:] трюка, который был упомянут. Более общего назначения для копирования вещей - использовать copy модуль.

Тем не менее, хороший код Python обычно не требует явно скопированного вещей очень часто. Вы должны познакомиться с использованием понятных списков для создания «модифицированных версий» существующих последовательностей. Например, мы можем реализовать сито как (демонстрируя несколько других вещей):

import sys, argparse, math, itertools

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

# Using a loop over a 'range' to fill a list with increasing values is silly, because
# the range *is* a list of increasing values - that's how the 'for i in ...' bit works.
sieve = range(2, args.n + 1)

# We don't need to remember the original loop at all.
# Instead, we rely on each iteration of the sieve putting a new prime at the beginning.
for index in itertools.count(): # Counting upward,
  if index >= len(sieve): break # until we run out of elements,
  prime = sieve[index] # we grab the next prime from the list,
  sieve = [x for x in sieve if x == prime or x % prime != 0] # and sieve the list with it.
# Of course, we can optimize that by checking that prime < sqrt(args.n), or whatever.

print sieve

Я не мог проверить это, потому что у меня нет копии Python 3.2 (argparse Новый в Python 3.2), но на ум приходит две очевидные вещи:

Во-первых, вам нужно сделать sieve.append(int(i)) .

Во-вторых, вы не делаете копию сита, вы просто создаете новую ссылку на тот же список. Сделать копию, вам нужно

copy1 = sieve[:]
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top