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

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

许多初学者在尝试在while或for循环中放入if/else块时无意中发现了这种语法,并且没有正确地缩进else。解决方案是确保else块与if块对齐,假设您打算对它们进行配对。这个问题解释了为什么它没有导致语法错误,以及产生的代码意味着什么。我还得到了一个IndentationError。我该怎么解决呢?,用于报告语法错误的情况。


当前回答

请允许我举例说明为什么要使用else子句。但是:

我的观点在Leo的回答中得到了更好的解释 我使用for-而不是while-循环,但else工作类似(除非遇到break,否则执行) 有更好的方法可以做到这一点(例如,将其包装到函数中或引发异常)

打破多级循环

它是这样工作的:外部循环在结尾有一个break,所以它只会执行一次。但是,如果内部循环完成(没有找到除数),那么它将到达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!'

其他回答

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

正如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循环后检查condition,而是用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来理解代码,这种语法对我来说更有意义。

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

所以输出是这样的:

5
4
3
2
1
what the...

As far as I know the main reason for adding else to loops in any language is in cases when the iterator is not on in your control. Imagine the iterator is on a server and you just give it a signal to fetch the next 100 records of data. You want the loop to go on as long as the length of the data received is 100. If it is less, you need it to go one more times and then end it. There are many other situations where you have no control over the last iteration. Having the option to add an else in these cases makes everything much easier.

我的回答将集中在我们什么时候可以使用while/for-else。

乍一看,使用时似乎没有什么不同

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

and

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

因为打印'ELSE'语句似乎总是在这两种情况下执行(当while循环结束或不运行时)。

然后,只有当打印'ELSE'语句不被执行时,情况才有所不同。 它是在while下面的代码块中有一个突破

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

如与:

In [19]: i = 0

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

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

异常引发也不会造成差异,因为当它引发时,下一个代码将在异常处理程序中执行(block除外),else子句或while子句后面的代码将不会被执行。

如果while循环没有中断,则执行Else。

我有点喜欢用“跑步者”来比喻。

“else”就像越过终点线,与你是从赛道的起点还是终点出发无关。"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