Python while语句的其他子句

问题:Python while语句的其他子句

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

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

I’ve noticed the following code is legal in Python. My question is why? Is there a specific reason?

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

回答 0

else仅当您的while条件为假时才执行该子句。如果您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()

The else clause is only executed when your while condition becomes false. If you break out of the loop, or if an exception is raised, it won’t be executed.

One way to think about it is as an if/else construct with respect to the condition:

if condition:
    handle_true()
else:
    handle_false()

is analogous to the looping construct:

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

An example might be along the lines of:

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()

回答 1

else如果您通过退出循环条件或掉落try块的底部来正常退出一个块,则执行该子句。它执行,如果你break还是return一个块外,或引发异常。它不仅适用于while和for循环,还可以尝试块。

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

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

The else clause is executed if you exit a block normally, by hitting the loop condition or falling off the bottom of a try block. It is not executed if you break or return out of a block, or raise an exception. It works for not only while and for loops, but also try blocks.

You typically find it in places where normally you would exit a loop early, and running off the end of the loop is an unexpected/unusual occasion. For example, if you’re looping through a list looking for a value:

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

回答 2

作为对的答复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已使用,否则该语句将在最后执行。

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

In reply to Is there a specific reason?, here is one interesting application: breaking out of multiple levels of looping.

Here is how it works: the outer loop has a break at the end, so it would only be executed once. However, if the inner loop completes (finds no divisor), then it reaches the else statement and the outer break is never reached. This way, a break in the inner loop will break out of both loops, rather than just one.

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!'

For both while and for loops, the else statement is executed at the end, unless break was used.

In most cases there are better ways to do this (wrapping it into a function or raising an exception), but this works!


回答 3

当while条件评估为false时,将执行else子句。

文档中

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

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

这将反复测试表达式,如果为true,则执行第一个套件;否则,将执行第一个套件。如果表达式为假(可能是第一次测试)else,则执行该子句的套件(如果存在),并终止循环。

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

The else-clause is executed when the while-condition evaluates to false.

From the documentation:

The while statement is used for repeated execution as long as an expression is true:

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

This repeatedly tests the expression and, if it is true, executes the first suite; if the expression is false (which may be the first time it is tested) the suite of the else clause, if present, is executed and the loop terminates.

A break statement executed in the first suite terminates the loop without executing the else clause’s suite. A continue statement executed in the first suite skips the rest of the suite and goes back to testing the expression.


回答 4

我的回答将集中于何时可以使用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'不执行该语句时有所不同。这是break在下面的代码块中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 不在此类别中,因为它对以上两种情况具有相同的效果。

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

My answer will focus on WHEN we can use while/for-else.

At the first glance, it seems there is no different when using

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

and

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

Because the print 'ELSE' statement seems always executed in both cases (both when the while loop finished or not run).

Then, it’s only different when the statement print 'ELSE' will not be executed. It’s when there is a breakinside the code block under 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

If differ to:

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 is not in this category, because it does the same effect for two above cases.

exception raise also does not cause difference, because when it raises, where the next code will be executed is in exception handler (except block), the code in else clause or right after the while clause will not be executed.


回答 5

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

就像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为了理解代码,而语法对我来说更有意义。

I know this is old question but…

As Raymond Hettinger said, it should be called while/no_break instead of while/else.
I find it easy to understeand if you look at this snippet.

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

Now instead of checking condition after while loop we can swap it with else and get rid of that check.

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

I always read it as while/no_break to understand the code and that syntax makes much more sense to me.


回答 6

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

这里有些例子:

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

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 < 5成为当假i5,所以else从句被执行。

i = 0

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

输出:

0
1
2
3
4
this

The else clause is only executed when the while-condition becomes false.

Here are some examples:

Example 1: Initially the condition is false, so else-clause is executed.

i = 99999999

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

OUTPUT:

this

Example 2: The while-condition i < 5 never became false because i == 3 breaks the loop, so else-clause was not executed.

i = 0

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

OUTPUT:

0
1
2
3

Example 3: The while-condition i < 5 became false when i was 5, so else-clause was executed.

i = 0

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

OUTPUT:

0
1
2
3
4
this

回答 7

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

所以输出是这样的:

5
4
3
2
1
what the...

The else: statement is executed when and only when the while loop no longer meets its condition (in your example, when n != 0 is false).

So the output would be this:

5
4
3
2
1
what the...

回答 8

如果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.

主要用例是使用这种脱离嵌套循环的方式,或者仅在循环未在某个地方中断的情况下才想运行某些语句(认为中断是一种不寻常的情况)。

例如,以下是关于如何不使用变量或不尝试/不抓住而跳出内部循环的机制:

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

Else is executed if while loop did not break.

I kinda like to think of it with a ‘runner’ metaphor.

The “else” is like crossing the finish line, irrelevant of whether you started at the beginning or end of the track. “else” is only not executed if you break somewhere in between.

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.

Main use cases is using this breaking out of nested loops or if you want to run some statements only if loop didn’t break somewhere (think of breaking being an unusual situation).

For example, the following is a mechanism on how to break out of an inner loop without using variables or 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

回答 9

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

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

The better use of ‘while: else:’ construction in Python should be if no loop is executed in ‘while’ then the ‘else’ statement is executed. The way it works today doesn’t make sense because you can use the code below with the same results…

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

回答 10

这对于社交互动很有用。

while (Date != "January 1st"):
    time.sleep(1)
else:
    print("Happy new year!")

It is useful for social interaction.

while (Date != "January 1st"):
    time.sleep(1)
else:
    print("Happy new year!")