Python while语句中的Else子句

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

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

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

244533 次浏览

else子句仅在while条件为false时执行。如果你break出了循环,或者引发了异常,它将不会被执行。

一种考虑它的方法是作为一个关于条件的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-condition的值为false时,else子句将被执行。

文档:

只要表达式为真,while语句就用于重复执行:

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

这将重复测试表达式,如果为真,则执行第一个套件;如果表达式为false(这可能是它第一次测试),则执行else子句的集合,并终止循环。

在第一个套件中执行的break语句将终止循环,而不执行else子句的套件。在第一个套件中执行的continue语句将跳过套件的其余部分,并返回测试表达式。

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

所以输出是这样的:

5
4
3
2
1
what the...

else子句在正常退出块的情况下执行,例如击中循环条件或脱离try块的底部。如果从块中breakreturn,或引发异常,则执行。它不仅适用于while和for循环,还适用于try块。

您通常会在通常会提前退出循环的地方发现它,并且在意想不到/不寻常的情况下运行到循环的末尾。例如,如果你在一个列表中循环寻找一个值:

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

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

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

作为Is there a specific reason?的回复,这里有一个有趣的应用:打破多级循环。

它是这样工作的:外部循环在结尾有一个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!'

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

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

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

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

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

而且

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

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

只有当语句print 'ELSE'不被执行时才会有所不同。 它是在while

下面的代码块中有__abc0
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

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

正如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条件为false时执行。

下面是一些例子:

示例1:初始条件为false,因此执行else子句

i = 99999999


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

输出:

this

示例2: while条件 i < 5永远不会变成false,因为i == 3打破了循环,所以else子句没有被执行。

i = 0


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

输出:

0
1
2
3

i5时,while条件 i < 5变为false,因此执行else子句

i = 0


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

输出:

0
1
2
3
4
this

据我所知,在任何语言中为循环添加else的主要原因是在控件中没有打开迭代器的情况下。假设迭代器在服务器上,你只是给它一个信号,让它获取下100条数据记录。只要接收到的数据长度为100,循环就会继续。如果少了,你需要再走一遍,然后结束。还有许多其他情况,您无法控制最后的迭代。在这些情况下,可以选择添加else,这使得一切都变得简单得多。

假设要在单链表中搜索元素x

    def search(self, x):
position = 1
p =self.start
while p is not None:
if p.info == x:
print(x, " is at position ", position)
return True
position += 1
p = p.link
else:
print(x, "not found in list")
return False

因此,如果条件失败,其他将执行,希望它有助于!