【问题标题】:Python infinite loop with for elsePython无限循环与for else
【发布时间】:2021-02-02 20:30:30
【问题描述】:

我正在编写一个计算素数的函数。我尝试使用嵌套在 while 循环中的 for-break-else 框架。但是,我得到了一个无限循环。我知道else 没有正确的缩进。在我将else 向前移动并使其与for, 平行后,问题就解决了。但是,我很难理解为什么else 块的原始位置会给我无限循环。有人可以帮我吗?谢谢。

def count_primes(num):
    primes = [2]
    x = 3
    if num < 2:
        return 0
    else:
        while x <= num:
            for y in range(3,x,2):
                if x%y ==0:
                    x += 2
                    break #jump out the for loop
                else:
                    primes.append(x)
                    x +=2 
    return primes
                    

【问题讨论】:

  • x3 开头,循环为for y in range(3,x,2):。循环永远不会执行,所以 x 永远不会改变。
  • 永远不会执行for循环块
  • 这是因为range(3,x,2) 给出了一个空的可迭代对象,所以for 块永远不会被执行,x+=2break 永远不会被调用。那么,while x&lt;= num 总是 True 会导致无限循环吗?

标签: python loops for-loop while-loop break


【解决方案1】:

在您的函数中,您将变量 x 初始化为 3,但在 for 循环中,您将循环范围定义为从 y = 3 到 x = 3。您应该记住范围函数 range(a,b )a 到 (b-1)。因此,您的循环试图循环 3 到 2,这是不可能的,因此您永远不会执行其中的代码。这就是为什么你有一个无限循环,因为它总是试图运行循环,然后不能,然后回到 while 循环,而不增加 x。

为了您的代码,我会将 x 初始化为 5 以执行循环:

def count_primes(num):
    primes = [2]
    x = 5
    if num < 2:
        return 0
    else:
        while x <= num:
            for y in range(3, x, 2):
                if x % y == 0:
                    x += 2
                    break  # jump out the for loop
                else:
                    primes.append(x)
                    x += 2
    return primes

但是经过测试,很明显您的代码不会给您正确的答案。用 num = 100 测试你的函数会得到以下结果,这是不正确的(例如 21 不是质数):

>>> count_primes(100)
[2, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, 129]

为了与您尝试实现的逻辑保持一致,这是返回列表或素数的另一种解决方案:

def count_primes(num):
    if num <= 1:
        return []

    primes = [2]
    x = 3
    while x <= num:
        is_prime = True
        for prime_numbers in primes:
            if x % prime_numbers == 0:
                is_prime = False
                break
        if is_prime:
            primes.append(x)
        x += 2
    return primes

用 num = 100 对其进行测试,可以得到 100 以下的素数的正确列表:

>>> count_primes(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]

【讨论】:

    【解决方案2】:

    Python 使用缩进来表示代码块。 如果 else 与 if 一起使用,则每次 if 错误时都会触发它。这将 x 的值增加 x+=2。这会在每次 if 语句为 false 时增加循环的范围,从而导致无限循环。 当 else 与 for 并行时,只有当 for 循环条件为 false 时才会执行 x+=2 语句。

    else:
    primes.append(x)
    x +=2 
    

    【讨论】:

    • 是的。这是一个问题。但是即使x连续增加2,当x%y被求值时,如果x可以在没有提醒的情况下除以3,它仍然有机会调用break并跳出for循环。如果x 是一个大于num 的数字,它可以被3 整除,它将打破for 循环和while 循环。这就是为什么我认为无限循环不应该发生并且无法弄清楚的原因。
    猜你喜欢
    • 2021-09-16
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多