Упорядочение оценки с использованием логического или - PullRequest
0 голосов
/ 23 августа 2010

Итак, у меня есть этот фрагмент кода. И это работает (говорит, что 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, поэтому порядок не учитывается?

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

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

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

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

Ответы [ 5 ]

2 голосов
/ 23 августа 2010

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

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

1 голос
/ 23 августа 2010

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

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

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

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

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

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

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

1 голос
/ 23 августа 2010

Приоритет штраф . Сначала оценивается %, затем ==, затем 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 - это все, что нужно.

1 голос
/ 23 августа 2010

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

0 голосов
/ 23 августа 2010
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.

...