Заявление 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
Другие вопросы по тегам