2013-05-19 4 views
0

Я только начинаю, и я написал следующий код и пытался его отладить в течение нескольких часов. Я не понимаю здесь ничего общего. Я хочу, чтобы код дал мне список простых чисел до длины, указанных в параметре вызова. Я начал со списком первых четырех, просто чтобы добиться успеха и упростить кодирование. Основной алгоритм, который я хочу использовать, состоит в том, чтобы добавить два к последнему члену списка, а затем проверить, является ли последний номер в списке простым, определяя, разделяют ли его остальные члены, начиная с первого члена. Я хотел бы прекратить проверку в тот момент, когда значение делителя превышает квадратный корень из числа кандидатов, но я не понял, как это сделать.Создание списка простых чисел. - beginner

Я получаю сообщение об ошибке в строке 5, которую я не могу понять, но я уверен, что есть и другие проблемы с кодом.

def prime_list(length): 
    L = [2, 3, 5, 7] 
    j = 9 

    while length > len(L): 
     prime = True 
     i = 0 
     for divisor in L: 
      while divisor in range (0, len(L) - 2) and prime == True: 
       if j % divisor == 0: 
        prime = False 
     if prime == False: 
      j = j + 2 
     else: 
      L = L.append(j) 
    return L 
+0

Какая ошибка? – karthikr

+1

Возможно, я не читаю достаточно близко, но 'i', похоже, не используется снова после того, как вы присвоите ему значение 0. –

+0

Ваш цикл 'while' будет работать вечно, если' divisor' не является делителем. – Blender

ответ

0

Если length > len(L) не работает, это, скорее всего, проблема с типами. вы сравниваете строку с целым числом, например.

range (0, len(L) - 2): Вы можете быть уверены, что len(L) - 2 больше или равно 0?

Посмотрите на этот генератор: http://code.activestate.com/recipes/366178-a-fast-prime-number-list-generator/

+0

'L = [2, 3, 5, 7]' so 'len (L)' не сложно понять. –

+0

yes, 'len (L)' работает как ожидалось – mrKelley

+0

@JochenRitzel ... что, если smbd передает строковый аргумент? наверняка len работает !!!! – octoback

0

L = L.append(j) Оператор не имеет эффекта, который вы ожидаете. Двойная проверка в руководстве.

1

.append() изменяет список на свои места None. Не назначайте None, он возвращается к L.

0

Ваш while цикл будет продолжаться вечно, если j не является делителем:

while divisor in range (0, len(L) - 2) and prime == True: 

L.append(j) возвращает None, так что вы установите L в None когда вы добавляете к нему.

Возможно, было бы полезно посмотреть, как это сделает кто-то другой. Я бы написал так:

def prime_list(num): 
    # Start off with the first two primes 
    primes = [2, 3] 

    # The test number is the last prime + 2 
    n = primes[-1] + 2 

    while len(primes) < num: 
     # For every prime smaller than n 
     for prime in primes: 
      # If the prime divides n 
      if n % prime == 0: 
       # n isn't prime. Break out of the loop. 
       break 
     else: 
      # We didn't break out of the loop, so n is prime 
      primes.append(n) 

     # Add 2 to the test number 
     n += 2 

    return primes 
1

Я уверен, что ваша проблема здесь:

L = L.append(j)

вобще L.append(j), а затем L будет список вы хотите быть.

Вы устанавливаете L на возврат метода append(), который, вероятно, ничего.

И да, могут возникнуть некоторые другие проблемы с логикой вашего кода, но продолжайте!

Поскольку другие люди дошли до этого ответа передо мной, я объясню вам, как я это понял. len(L) должен работать, поскольку вы определили L как список.Я хотел бы видеть, когда в то время цикла это происходит, поэтому я вставил print() сразу после цикла начинается так:

while length > len(L): 
    print('check') 
    prime = True 
    ... 

Это только печатает «проверить» один раз, так что означает, что цикл выполняется один раз, а затем вы получите эту ошибку. Это заставило меня искать, где вы изменяли L в цикле. Выступал оператор append(), а затем ошибка имеет смысл: TypeError: object of type 'NoneType' has no len(). Вы бессознательно установили L в None в этой строке.

PS: print() всегда ваш друг для отладки

0

Все четные числа> 2 не являются простыми числами, потому что вы можете разделить их на 2. Таким образом, вы можете создать список нечетных чисел> 3 числа, как это:

def prime_list(length): 
    candidates = list(range(3, length, 2)) 

пример для Lenth = 17

In [1]: length = 17 

In [2]: list(range(3, length, 2)) 
Out[2]: [3, 5, 7, 9, 11, 13, 15] 

Теперь для всех чисел N в этом списке, вы должны убедиться, что N по модулю один из предыдущих чисел не равно нулю. Это может быть сделано с all функции и список понимания:

L = [] 
    for c in candidates: 
     if all([c % p != 0 for p in range(2,c)]): 
      L.append(c) 

Давайте дадим это попробовать для, например, число 39:

In [1]: [39 % p != 0 for p in range(2,39)] 
Out[1]: [True, False, True, True, True, True, True, True, True, True, True, False, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] 

Второй элемент в списке является ложным, потому что 39% 3 = 0. Таким образом, 39 не является простым. Если есть один или несколько False значений в списке, all() возвратит ложь:

In [3]: all([39 % p != 0 for p in range(2,39)]) 
Out[3]: False 

Вторым примером является число 17:

In [3]: [17 % p != 0 for p in range(2,17)] 
Out[3]: [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] 

In [4]: all([17 % p != 0 for p in range(2,17)]) 
Out[4]: True 

Так 17 является простым числом.

Список L теперь содержит простые числа, за исключением 1 и 2, поэтому выполнение функции:

def prime_list(length): 
    candidates = list(range(3, length, 2)) 
    L = [] 
    for c in candidates: 
     if all([c % p != 0 for p in range(2,c)]): 
      L.append(c) 
    return [1, 2] + L 

Вы можете даже заменить для цикла быть список понимания, а, кипячение функции до трех строк кода:

def prime_list(length): 
    candidates = list(range(3, length, 2)) 
    L = [c for c in candidates if all(c % p != 0 for p in range(2,c))] 
    return [1,2] + L 
Смежные вопросы