Заявление For-Else с несколькими условиями If-Break
Я написал простой модуль Python, который возвращает простые числа до заданного N, используя флаг bool is_prime
следующее:
def generate_primes_up_to(M):
n = 2
primes = []
while n <= M:
is_prime = True
for p in primes:
if p**2 > n: break
if n % p == 0:
is_prime = False
break
if is_prime: primes.append(n)
n += 1
return primes
if __name__ == '__main__':
generate_primes_up_to(100)
какие выводы:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
Теперь это на самом деле идеальный случай для использования for-else
построить, так как число n
простое, только если нет break
произошло в for
петля. Таким образом, я изменил функцию на:
def generate_primes_up_to(M, flag='nonumpy'):
n = 2
primes = []
while n <= M:
for p in primes:
if p**2 > n: break
if n % p == 0: break
else: primes.append(n)
n += 1
return primes
но теперь код выводит:
[2, 5, 27]
Я не понимаю, почему if p**2 > n: break
выражение мешает потоку for-else
пункт. Если я уберу эту строку, код снова выдаст правильный вывод.
2 ответа
Состояние, вызывающее проблему:
if p**2 > n: break
Давайте возьмем пример - 7
Когда мы проверяем, является ли 7 простым или нет, мы уже выяснили, что - [2,3,5]
простые числа, указанное выше условие нарушает for
цикл, когда мы проверяем 3
как 3**2
знак равно 9
который больше чем 7
,
Удалите это условие, и оно работает нормально (хотя и очень медленно).
В исходном цикле (без конструкции for-else) это работало, потому что в этом состоянии вы просто вышли из цикла, вы не изменили флаг is_prime
,
С for..else
построить, что происходит то, что else
часть выполняется только когда мы выходим из цикла без использования break
заявление.
Но в случае вышеуказанного условия мы используем break
заявление и, следовательно, else
часть не выполнена.
Вы также можете использовать next
:
def generate_primes_up_to(M):
n = 2
primes = []
while n <= M:
if next((False for p in primes if not n % p), True):
primes.append(n)
n += 1
return primes