我注意到以下代码在Python中是合法的。我的问题是为什么?有特定原因吗?

n = 5
while n != 0:
    print n
    n -= 1
else:
    print "what the..."


评论

@detly:那是因为大多数人都避免这种构造。 :)我相信Guido在Py3k流程中提到,至少,为此目的选择其他单词是一个非常糟糕的主意,并且他们将不再做这些事情。

@尼古拉斯·奈特(Nicholas Knight)-是的,虽然很诱人,但可能只有我乍一看才知道。任何其他较差的汁液都必须去看一下语言规格,或者回到过去并在此处发表问题...

选择“ else”背后的想法是,该结构通常与while循环内的“ if X:break”结合使用。由于如果不中断循环就会执行'else'子句,因此它对'if'形成了一种“ else”。

他们应该在以下名称后重命名:。

为什么python在for和while循环之后为什么使用'else'的可能重复?

#1 楼

仅当您的else条件变为假时才执行while子句。如果您退出循环,或者引发了异常,则将不会执行该异常。

一种考虑它的方式是关于条件的if / else构造:

if condition:
    handle_true()
else:
    handle_false()


类似于循环构造:

while condition:
    handle_true()
else:
    # condition is false now, handle and go on with the rest of the program
    handle_false()


示例可能类似于:

while value < threshold:
    if not process_acceptable_value(value):
        # something went wrong, exit the loop; don't pass go, don't collect 200
        break
    value = update(value)
else:
    # value >= threshold; pass go, collect 200
    handle_threshold_reached()


评论


“只有当您的while条件变为false时,才执行else子句。”这里的措辞意味着您的while状态从true变为false,然后其他状态将被执行。但是,如果while永远都不为真,则else子句仍将执行。

–user597608
2014年10月10日21:11

伪代码因此,如果我错了,请纠正我,但这与while {}某些内容完全相同,只是如果您在while循环中中断,这些内容将被跳过。

–丹尼尔·卡普兰(Daniel Kaplan)
15年3月18日在21:48



也许最精确的伪代码是:while(True){if(cond){handle_true(); }其他{handle_false();打破; }}

– VinGarcia
16 Dec 5'在14:46

“不走,不收200”,哈哈,每个人都知道这是哪里的

– Stefan Octavian
19年4月8日在17:09

即使while条件变为false,即使while循环以'break'结尾,也不执行else子句。例如,在休息前将条件更改为false。

– starriet
20年8月5日,下午2:30

#2 楼

如果您通过退出循环条件或脱离try块的底部正常退出块,则将执行else子句。如果breakreturn超出一个块或引发异常,则不会执行该操作。它不仅适用于while和for循环,还可以尝试块。

您通常会在通常会提早退出循环的地方找到它,而在循环结束时运行是意外的/不寻常的场合。例如,如果要遍历列表以查找值:

for value in values:
    if value == 5:
        print "Found it!"
        break
else:
    print "Nowhere to be found. :-("


评论


实际上,这是一个相当有用的构造。不知道我在循环开始时放置了found_it = False多少次,然后在结束时对found_it进行了if检查

– Cruncher
20-2-19在18:51

#3 楼

作为对Is there a specific reason?的答复,这是一个有趣的应用程序:打破多级循环。

这是它的工作方式:外循环在末尾有一个中断,因此只能执行一次。但是,如果内部循环完成(未找到除数),那么它将到达else语句,并且永远不会到达外部中断。这样,内部循环中的中断将同时出现在两个循环中,而不仅仅是一个循环。

for k in [2, 3, 5, 7, 11, 13, 17, 25]:
    for m in range(2, 10):
        if k == m:
            continue
        print 'trying %s %% %s' % (k, m)
        if k % m == 0:
            print 'found a divisor: %d %% %d; breaking out of loop' % (k, m)
            break
    else:
        continue
    print 'breaking another level of loop'
    break
else:
    print 'no divisor could be found!'


对于whilefor循环,都执行else语句最后,除非使用了break

在大多数情况下,有更好的方法(将其包装为函数或引发异常),但这是可行的!

评论


我没有投票,但我想我知道为什么有人这样做。您没有回答问题,而是提供了14行代码以及仅2行描述。如果与所问的问题有关,您是不是在告诉我们...

– BlueEel
2014年12月1日12:01

@BlueEel感谢您的反馈!我添加了有关代码的更多解释,并使其更清楚地回答了问题(因为它确实回答了部分问题)。

–马克
2014年12月3日,12:52

您设法将代码放在上下文中,尽管您没有回答所有问题,但我现在看到了相关性。我赞成您的回答,因为它对新手和新手(就python而言,对我自己来说)非常有用。 -谢谢,我学到了一些东西。

– BlueEel
2014年12月3日23:31

我喜欢简单的应用程序-现在,我明白了为什么有人会使用它。虽然我从未见过需要它。

– Gabe
2015年2月25日在10:23

该示例显示了for / else的用法,但问题专门针对while / else。

–伊恩·戈德比(Ian Goldby)
18年2月21日在10:28



#4 楼

当while条件的条件值为false时,将执行else子句。
从文档:

只要表达式为真,while语句就可以重复执行:
while_stmt ::=  "while" expression ":" suite
                ["else" ":" suite]

反复测试表达式,如果为true,则执行第一个套件;如果表达式为假(可能是第一次测试),则执行else子句套件(如果存在),并且循环终止。
在第一个套件中执行的break语句终止循环而不执行else子句的套件。在第一个套件中执行的continue语句会跳过套件的其余部分,并返回到测试表达式。


#5 楼

我的答案将集中在何时可以使用while / for-else上。

乍一看,使用
<43 78qq



while CONDITION:
    EXPRESSIONS
print 'ELSE'
print 'The next statement'


因为在两种情况下(总是在print 'ELSE'循环完成或未运行时)总是执行while语句。

然后,仅当不执行语句print 'ELSE'时才有所不同。
这是在break下的代码块中有一个while

while CONDITION:
    EXPRESSIONS
else:
    print 'ELSE'
print 'The next statement'


如果与以下内容不同:

In [17]: i = 0

In [18]: while i < 5:
    print i
    if i == 2:
        break
    i = i +1
else:
    print 'ELSE'
print 'The next statement'
   ....:
0
1
2
The next statement


return不在此类别中,因为它在上述两种情况下具有相同的效果。

exception引起的差异也不大,因为当它引发时,将在下一个代码处执行在异常处理程序(块除外)中,将不会执行else子句中或紧接在while子句之后的代码。

#6 楼

else子句仅在while条件变为false时才执行。

以下是一些示例:

示例1:最初条件为false,因此执行else-clause 。

i = 99999999

while i < 5:
    print(i)
    i += 1
else:
    print('this')


输出:

this


示例2:同时条件i < 5永远不会因为i == 3而变为假中断循环,因此未执行else子句。

i = 0

while i < 5:
    print(i)
    if i == 3:
        break
    i += 1
else:
    print('this')


输出:

0
1
2
3


示例3 :当i < 5i时,while条件5变为false,因此执行了else子句。

i = 0

while i < 5:
    print(i)
    i += 1
else:
    print('this')


输出:

0
1
2
3
4
this

/>

#7 楼

我知道这是个老问题,但是...

正如Raymond Hettinger所说,应该将其命名为while/no_break而不是while/else
如果您查看此摘要,我会很容易理解不足。

n = 5
while n > 0:
    print n
    n -= 1
    if n == 2:
        break
if n == 0:
    print n


现在,我们不用在while循环后检查条件,而是可以将其替换为else并摆脱该检查。

n = 5
while n > 0:
    print n
    n -= 1
    if n == 2:
        break
else:  # read it as "no_break"
    print n


我总是将其读为while/no_break以了解代码,并且语法对我而言更有意义。

#8 楼

仅当while循环不再满足其条件时才执行else:语句(在您的示例中,当n != 0为false时)。

所以输出将是这样的:

5
4
3
2
1
what the...


评论


我知道,但是这种while / else在Java中不起作用。当我发现它可以在Python中工作时,我发现它很有趣。我只是好奇,想知道技术原因。

–伊凡
2010年7月21日在2:57

@Ivan:并不是说它在Java中不起作用,而是在Java中不存在。如果有人愿意将其添加到语言中,则可以使其工作。

–伊格纳西奥·巴斯克斯(Ignacio Vazquez-Abrams)
2010年7月21日在7:52

不,虽然为False:.. else ..仍运行else子句。准确地说:else仅在中断循环时才运行。

– Leo Ufimtsev
19年7月29日在4:11

#9 楼

如果while循环没有中断,则会执行其他操作。

我有点想用“运行器”隐喻来思考它。

“其他”就像越过终点线,与您是从曲目的开头还是结尾开始无关。仅当您在它们之间的某个位置中断时,才会执行“ else”。

 runner_at = 0 # or 10 makes no difference, if unlucky_sector is not 0-10
unlucky_sector = 6
while runner_at < 10:
    print("Runner at: ", runner_at)
    if runner_at == unlucky_sector:
        print("Runner fell and broke his foot. Will not reach finish.")
        break
    runner_at += 1
else:
    print("Runner has finished the race!") # Not executed if runner broke his foot.
 


主要用途情况就是使用这种从嵌套循环中中断的情况,或者如果您只想在循环没有中断的地方运行某些语句(以为中断是一种不寻常的情况)。

例如,以下是关于如何在不使用变量或不尝试使用try / catch的情况下突破内部循环的机制:

 for i in [1,2,3]:
    for j in ['a', 'unlucky', 'c']:
        print(i, j)
        if j == 'unlucky':
            break
    else: 
        continue  # Only executed if inner loop didn't break.
    break         # This is only reached if inner loop 'breaked' out since continue didn't run. 

print("Finished")
# 1 a
# 1 b
# Finished
 


#10 楼

据我所知,在任何语言中向循环添加else的主要原因是在控件中未启用迭代器的情况下。想象一下,迭代器在服务器上,您只是给它一个信号以获取接下来的100条数据记录。您希望只要接收到的数据长度为100,循环就继续下去。如果循环数少于100,则需要再循环一次,然后结束循环。在许多其他情况下,您无法控制上一次迭代。在这些情况下,可以选择添加else使一切变得更加容易。

#11 楼

在Python中更好地使用'while:else:'构造应该是:如果在'while'中没有执行循环,则执行'else'语句。今天的工作方式没有意义,因为您可以使用下面的代码获得相同的结果...

n = 5
while n != 0:
    print n
    n -= 1
print "what the..."


评论


不,不同之处在于,如果使用break或return关键字退出循环,则else块将不会执行。在您的示例中,如果在break命令上循环已结束,则还将执行打印。

–不确定要做什么
13-10-21在16:43



您描述的是大多数人希望功能起作用的方式,而不是功能的实际作用!

– dotancohen
16-2-29在9:42