【问题标题】:Infinite while loop in python - with conflicting conditionspython中的无限while循环-条件冲突
【发布时间】:2021-10-22 11:54:22
【问题描述】:

我在“while 循环”函数中导致的拼写错误导致我提出以下问题

from time import sleep
from random import randint

def control_pressure():
    pressure = measure_pressure()
    while True:
        if pressure <= 500:
            break

        while pressure > 500 and pressure <= 700:
            run_standard_safeties()
            pressure = measure_pressure()

        while pressure > 100:                     # Here is the typo
            run_critical_safeties()
            pressure = measure_pressure()

    print("Wow! The system is safe...")

def measure_pressure():
    pressure = randint(450, 800)
    print(f"psi={pressure}", end="; ")
    return pressure

def run_standard_safeties():
    print("Running standard safeties...")
    sleep(0.2)

def run_critical_safeties():
    print("Running critical safeties...")
    sleep(0.7)

if __name__ == "__main__":
    control_pressure()

在上面,我打错了,检查了压力> 100,而条件。但是在函数的第一部分早些时候,它检查了,而压力 100 的情况下破坏函数。

但是这个功能一直没有停止。为什么会这样?

谢谢

【问题讨论】:

  • 您对return 和break 感到困惑。 return 终止函数,但 break 只中断循环。然后执行循环之后的所有语句
  • 如果外部while 循环没有中断,那仅意味着pressure 始终大于500,请尝试在外部while 循环中打印pressure。
  • 不,代码已经通过代码在 measure_pressure() 函数中显示了压力值 - print(f"psi={pressure}", end="; ")。但它仍然没有坏

标签: python python-3.x while-loop


【解决方案1】:

最好按顺序描述您的场景。

任何大于 500 的初始压力都会绕过break 并继续到第一个内循环。由于您得到一个随机值450..800(350 的范围 - 这里的范围可能相差一个,但它们足够接近以至于无关紧要),这有大约 300/350 的概率(分子来自500..800 范围)或85%。

只要您的压力在500..700 范围内,第一个内循环就会运行,概率约为200/350,即57%。

在某些时候,您将退出第一个内部循环并进入第二个内部循环。而您将输入它,因为450..800 范围内的所有值(您可能作为压力获得)都大于一百。

当然,这意味着您也永远不会退出该循环,因为在该点之后您所承受的压力不会是 100 或更少,这是退出循环所需要的。


顺便说一句,您实际上可以避免这种循环中的循环结构,方法是意识到您在每个循环的每次迭代中都会获得压力,因此可以使这种结构变得普遍。

假设您的拼写错误是使用100,您的意思是700(因为它的范围互斥),可以简化为:

def control_pressure():
    while True:
        pressure = measure_pressure()
        if pressure <= 500:
            print("Wow! The system is safe...")
            return

        if pressure <= 700:
            run_standard_safeties()
        else:
            run_critical_safeties()

或者,如果您想使用 := walrus 运算符(a)(我认为在 Python 3.8+ 中可用),您可以通过获取和检查压力作为一部分来进一步缩短它while 声明:

def control_pressure():
    while (pressure := measure_pressure()) > 500:
        if pressure <= 700:
            run_standard_safeties()
        else:
            run_critical_safeties()
    print("Wow! The system is safe...")

(a) 之所以这么叫,是因为如果你顺时针旋转 90° 并眯着眼睛,它看起来就像一只拥有两只眼睛和两根巨大獠牙的海象。

它基本上(在这种情况下)允许您为变量分配一个值,作为检查所述变量的一部分,以便该值也可用于以后的检查。

【讨论】:

    【解决方案2】:

    如果初始数字大于 100 且大于 500,它将进入第二个循环并且永远不会停止,因为它将始终大于 100,因为您从 450-800 中随机抽取一个。

    【讨论】:

    • 想象一下,随机数是 460,对于第一个条件压力 100 是正确的,但从技术上讲,循环不应该到达那里,因为第一个条件已经满足,它应该在那里打破循环。但是,循环继续无限运行
    • 如果数字是 460,主循环应该退出。我试图重新创建您提到的错误但不能,因为pressure=460 主循环确实中断并且程序完成
    猜你喜欢
    • 2021-10-31
    • 2012-08-28
    • 2017-10-12
    • 2020-11-30
    • 2015-05-22
    • 2018-08-30
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    相关资源
    最近更新 更多