简体   繁体   English

具有多个If-Break条件的For-Else语句

[英]For-Else Statement with Multiple If-Break Conditions

I wrote a simple python module that returns the prime numbers up to a given N, using a bool flag is_prime as follows: 我编写了一个简单的python模块,该模块使用bool标志is_prime如下,将质数返回到给定的N:

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)

which outputs: 输出:

[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]

Now, this is actually an ideal case for using the for-else construct, since the number n is prime only if no break s occurred in the for loop. 现在,这实际上是使用for-else构造的理想情况,因为只有在for循环中没有break发生时,数字n才是质数。 Thus, I changed the function into: 因此,我将函数更改为:

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

but now the code outputs: 但是现在代码输出:

[2, 5, 27]

I don't understand why the if p**2 > n: break expression is interfering with the flow of the for-else clause. 我不明白为什么if p**2 > n: break表达式会干扰for-else子句的流程。 If I remove that line the code yields the right output again. 如果我删除该行,代码将再次产生正确的输出。

The condition causing the issue is - 导致该问题的条件是-

if p**2 > n: break

Lets take an example - 7 , when we are checking if 7 is prime or not , we have already found out that - [2,3,5] are primes, the above condition breaks the for loop, when we check 3 as 3**2 = 9 which is greater than 7 . 让我们举一个例子7 ,当我们检查7是否为质数时,我们已经发现- [2,3,5]为质数,当我们将3视为3**2时,上述条件打破了for循环。 3**2 = 9 ,大于7

Remove that condition and it works fine (Though its very slow). 删除该条件,它可以正常工作(尽管非常慢)。

In the original loop (without the for-else construct) , it worked because in that condition you just broke out of the loop, you did not change the flag is_prime . 在原始循环中(没有for-else构造),它之所以起作用,是因为在这种情况下,您刚脱离循环,没有更改标志is_prime


With the for..else construct, what happens is that, the else part is only executed when we exit the loop without using break statement. 使用for..else构造时,会发生的事情是, else部分仅在我们退出循环时才执行,而不使用break语句。

But in the case of the above condition , we use break statement and hence else part is not executed. 但在上述条件的情况下,我们利用break语句,因此else不执行的一部分。

You can also use next : 您还可以使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM