2010-08-23 2 views
0

Итак, у меня есть этот фрагмент кода. И это работает (Это говорит 1 не является простым) .:Порядок оценки с использованием булевых или

n = 1 
s = 'prime' 
for i in range(2, n/2 + 1): 
    if n == 1 or n % i == 0: 
     s= 'non-' +s 
     break 

print s 

Моя проблема заключается в том, что если я изменяю четвертую строку: if n % i == 0 or n == 1:, он не работает (он говорит, что 1 является простым.)

Почему? Так как я использую or, должно ли оно быть одним из них True, поэтому заказ не учитывается?

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

Заранее спасибо!

EDIT: Спасибо за ответы; Я никогда не осознавал свою проблему с функцией range(). А про код работает и не работает: я понятия не имею, что произошло. Возможно, я ошибся где-то по пути (возможно, забыл сохранить, прежде чем запускать скрипт. Хотя я мог бы поклясться, что это сработало по-другому: P). Может быть, я просто устаю ...

Спасибо за ответы в любом случае!

+0

Если вы пытаетесь проверить, является ли 'n' простым, вам нужно только проверить квадратный корень из' n'. – carl

+0

, как указывают ответы, цикл не запускается. Вы, должно быть, что-то изменили для своего кода, который когда-либо говорил, 1 не является простым. Кроме того, не забудьте «ломать», когда вы найдете коэффициент для 'n'. – aaronasterling

ответ

1

Приоритет fine. % оценивается первым, затем ==, затем or, поэтому он распадается на:

 ___or___ 
    /  \ 
    ==   == 
/\  /\ 
n 1  % 0 
     /\ 
      n i 

Ваша проблема заключается в том, что ваш цикл for не выполняется вообще, так что s все еще установлен в "prime".

Диапазон 2,n/2+1, когда n равен 1, соответствует 2,1, что приведет к тому, что тело не будет выполнено.

Фактически он не будет выполняться, если n равно 2, так как 2/2+1 равно 2, а диапазон 2,2 не выполняется. Значения начала и завершения значение, а не начало и конец (последнее) значение - это просто случайность, что там 2 считается простым в силу инициализации s :-)

Попробуйте вместо этого:

#!usr/bin/python 

n = 9 
s = 'prime' 
if n == 1: 
    s = 'non-prime' 
else: 
    i = 2 
    while i * i <= n: 
     if n % i == 0: 
      s= 'non-prime' 
      break 
     i = i + 1 
print s 

Это расточительно, вплоть до n/2, квадратный корень n - это все, что нужно.

+0

Я действительно этого не замечал: (... Но я понятия не имею, что случилось. Клянусь, что-то по-другому работало раньше, но я думаю, что я просто устаю, и я кое-что допустил по пути. Спасибо за ответ хотя! – avacariu

1

Я думаю, проблема в том, что n равно 1, цикл пропускается.

2

В обоих случаях тело цикла не запускается, потому что, когда «п» 1, он не попадает в диапазон (п, п/2 + 1)

Код вы вывесили говорит, что 1 является простым (опять же, потому что тело петли вообще не выполняется)

1

Других ответов уже правильно решать вашу конкретную проблему (которая, другими слова, является то, что цикл выполняется только тогда, когда n/2 + 1 > 2, то есть, n/2 > 1, что означает n > 2 с новым типом делением [[питоном 3 или подходящего импортом из будущее или флаги ...]], n > 3 с разделением классического стиля).

Wrt конкретный вопрос, который вы позировала:

Поскольку я использую или же она должна быть, что либо один из них является истинным, поэтому порядок не считается?

Порядок делает подсчет, потому что or (как and) короткое замыкание оператора: в частности, or является гарантированно идти слева направо, и остановится, если левый операнд истинно (потому что она делает не нужно знать о правильном). Это не имеет значения для конкретного кода, но это важно в таких случаях, как, например:

if i == 0 or n/i > 3: ... 

Если or не собиралось слева направо (и остановки ASAP), правая операнд может получить исполнение, даже если i равно 0 - но тогда дивизия поднимет исключение! С правилами Python этот фрагмент кода не будет генерировать исключения (если i - это int, по крайней мере ;-).

Снова: это не имеет ничего общего с конкретной проблемой, с которой вы сталкиваетесь (см. Другие ответы и начало этого), но важно знать о будущем, поэтому, поскольку вы спросили, я взял возможность объяснить! -)

+0

Спасибо за информацию или я понял, что это сработало, так как я заметил, что это происходит в каком-то другом коде, но я никогда не осознавал важность этого факта. Но я думаю, если нет никаких исключений, которые могут быть подняты, порядок не имеет значения, он все равно даст нужный результат. У меня еще есть чему узнать об этом :-) – avacariu

+0

@ vlad003 Заказ __can__ очень сильно зависит от кода, который зависит от него. Например, 'a = x или initialize_x()'. Хотя это плохой стиль, вы видите его вокруг, и важно понимать его, когда вы это делаете. Если значение 'x' равно true, оно эквивалентно' a = x'. в противном случае это эквивалентно 'x = initialize_x()'. Если вы измените порядок, то каждый раз вызывается 'initialize_x()'. – aaronasterling

0
for n in range(101): 
    s = 'prime' 
    if n < 2 or not (n & 1): ## not(n & 1) == is even number (last bit 0) == not (n % 2) 
     s = 'non-'+s 
    else: 
     for i in range(3, int(n**0.5) + 1,2): 
      if not(n % i): 
       s= 'non-' +s 
       break 
    print "%i is %s" % (n,s) 

Вам не нужно проверять все четные числа, и вы можете остановить проверку с квадратным корнем из n.

+0

вместо шага 2 во внутреннем диапазоне, вы можете начинать с 6 и шагать 6, проверяя i-1 и i + 1. вы должны проверить 3 вручную таким образом. – aaronasterling

+0

Мысль, что это было сложнее, как правило, только сбрасывать даже цифры из соображений. В противном случае я бы рассмотрел n% 30 действительных модулей для простых чисел. –

 Смежные вопросы

  • Нет связанных вопросов^_^