Python中while循环结束后的流程控制

3

我很新手,既不懂编程也不懂Python。几次尝试后,我感觉自己的程序流程有些令人不舒服,想知道是否遵循最佳实践。下面是我的想法:

def pseudocode():
    while some condition is true:
        do some stuff
        if a condition is met:
            break out of the while loop
    now do a thing once, but only if you never broke out of the loop above 

我最终做的东西虽然可行,但总感觉有些不对劲:

def pseudocode():
    while some condition is true:
        do some stuff
        if some condition is met:
            some_condition_met = True
            break out of the while loop

    if some_condition_met is False:
        do a thing

有更好的方法吗?

3个回答

9
您正在寻找while-else循环:
def pseudocode():
    while some condition is true:
        do some stuff
        if a condition is met:
            break out of the while loop
    else:
        now do a thing once, but only if you never broke out of the loop above 

来自文档:

while_stmt ::=  "while" expression ":" suite
                ["else" ":" suite]

在第一个语句组中执行的 break 语句会终止循环,而不会执行 else 子句的语句组。


哇,我之前不知道这个存在(显然!)。谢谢。 - Ben S.

3

while 循环中使用 else 子句:

while some_condition:
    do_stuff()
    if a_condition_is_met:
        break
else:
    executed_when_never_broken

请查看while语句文档:

在第一个代码块中执行break语句将终止循环,不会执行else块中的代码。


0

如果你仔细考虑,你可能已经有一个非常好的条件可以使用而无需设置标志:while循环顶部的条件(或者更确切地说是它的not)。假设在同一次迭代中你不改变条件的真实性和使用break,这就给你:

while something:
    do_stuff()
    if something_else:
        break
if not something:
   more_stuff()

如果你将while看作是重复的if,那么这就很有道理:不再只发生一次,而是当条件变为falsey时,while继续进行

但是,正如其他答案所提到的,这种类比可以进一步拓展:就像你不必将所有的if都拼写出来一样,

if a:
    a_stuff()
if not a:
    b_stuff()

while 接受一个 else,如果顶部的条件测试为 falsey,则执行该条件。

while something:
    do_stuff()
    if something_else:
       break
else:
    more_stuff()

同样的,与if/else情况相同,这并不意味着比本来会发生的条件测试更多。就像附加到if aelse在真分支使a为falsey时不会运行一样,附加到whileelsebreak之后永远不会运行,因为它明确跳过了再次检查条件。这使得else:在每种情况下都等同于专用标志。

这也适用于for循环,即使类比有所破坏-但它在类似的规则下执行:如果循环结束而不是遇到break,则运行else


1
请注意,else:子句和if not something测试可能会有微妙的差别。如果在循环期间while循环条件变为False并且您在同一次迭代中使用break,则else:套件将不会执行,但是您的if套件将会执行。 - Martijn Pieters
@MartijnPieters非常正确。我已经编辑了答案来解决这个问题。 - lvc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接