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

时间:2015-08-02 08:42:10

标签: python for-else

我编写了一个简单的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)

输出:

[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 s时,数字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 个答案:

答案 0 :(得分:4)

导致问题的条件是 -

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部分不会被执行。

答案 1 :(得分:1)

您还可以使用last Row

next