问题:为什么python在for和while循环之后使用’else’?

我了解此构造的工作原理:

for i in range(10):
    print(i)

    if i == 9:
        print("Too big - I'm giving up!")
        break;
else:
    print("Completed successfully")

但是我不明白为什么else在这里使用它作为关键字,因为这表明有问题的代码仅在for块未完成时才运行,这与它的工作相反!无论我如何考虑,我的大脑都无法从for陈述到else障碍的无缝发展。对我来说,continue还是continuewith更有意义(我正在尝试训练自己这样阅读)。

我想知道Python编码人员是如何在头脑中读取这个结构的(如果愿意,可以大声读出)。也许我缺少使这些代码块更容易理解的东西?

I understand how this construct works:

for i in range(10):
    print(i)

    if i == 9:
        print("Too big - I'm giving up!")
        break;
else:
    print("Completed successfully")

But I don’t understand why else is used as the keyword here, since it suggests the code in question only runs if the for block does not complete, which is the opposite of what it does! No matter how I think about it, my brain can’t progress seamlessly from the for statement to the else block. To me, continue or continuewith would make more sense (and I’m trying to train myself to read it as such).

I’m wondering how Python coders read this construct in their head (or aloud, if you like). Perhaps I’m missing something that would make such code blocks more easily decipherable?


回答 0

即使是经验丰富的Python程序员,这也是一个奇怪的构造。当与for循环结合使用时,它的基本含义是“在可迭代项中找到某个项目,否则,如果找不到任何项目,则执行…”。如:

found_obj = None
for obj in objects:
    if obj.key == search_key:
        found_obj = obj
        break
else:
    print('No object found.')

但是,只要您看到此构造,一个更好的选择就是将搜索封装在一个函数中:

def find_obj(search_key):
    for obj in objects:
        if obj.key == search_key:
            return obj

或使用列表理解:

matching_objs = [o for o in objects if o.key == search_key]
if matching_objs:
    print('Found {}'.format(matching_objs[0]))
else:
    print('No object found.')

它在语义上不等同于其他两个版本,但是在非性能关键代码中效果很好,在这里,您是否迭代整个列表都没有关系。其他人可能会不同意,但是我个人会避免在生产代码中使用for-else或while-else块。

另请参见[Python-思想] for … else线程的摘要

It’s a strange construct even to seasoned Python coders. When used in conjunction with for-loops it basically means “find some item in the iterable, else if none was found do …”. As in:

found_obj = None
for obj in objects:
    if obj.key == search_key:
        found_obj = obj
        break
else:
    print('No object found.')

But anytime you see this construct, a better alternative is to either encapsulate the search in a function:

def find_obj(search_key):
    for obj in objects:
        if obj.key == search_key:
            return obj

Or use a list comprehension:

matching_objs = [o for o in objects if o.key == search_key]
if matching_objs:
    print('Found {}'.format(matching_objs[0]))
else:
    print('No object found.')

It is not semantically equivalent to the other two versions, but works good enough in non-performance critical code where it doesn’t matter whether you iterate the whole list or not. Others may disagree, but I personally would avoid ever using the for-else or while-else blocks in production code.

See also [Python-ideas] Summary of for…else threads


回答 1

一个常见的构造是运行一个循环,直到找到某些东西,然后打破循环。问题是,如果我跳出循环或循环结束,则需要确定发生哪种情况。一种方法是创建一个标志或存储变量,这将使我进行第二次测试以查看循环是如何退出的。

例如,假设我需要搜索列表并处理每个项目,直到找到标记项目,然后停止处理。如果缺少标志项,则需要引发异常。

使用Python forelse构造

for i in mylist:
    if i == theflag:
        break
    process(i)
else:
    raise ValueError("List argument missing terminal flag.")

将此与不使用此语法糖的方法进行比较:

flagfound = False
for i in mylist:
    if i == theflag:
        flagfound = True
        break
    process(i)

if not flagfound:
    raise ValueError("List argument missing terminal flag.")

在第一种情况下,raise紧密绑定到它所使用的for循环。第二,绑定不那么牢固,并且在维护期间可能会引入错误。

A common construct is to run a loop until something is found and then to break out of the loop. The problem is that if I break out of the loop or the loop ends I need to determine which case happened. One method is to create a flag or store variable that will let me do a second test to see how the loop was exited.

For example assume that I need to search through a list and process each item until a flag item is found and then stop processing. If the flag item is missing then an exception needs to be raised.

Using the Python forelse construct you have

for i in mylist:
    if i == theflag:
        break
    process(i)
else:
    raise ValueError("List argument missing terminal flag.")

Compare this to a method that does not use this syntactic sugar:

flagfound = False
for i in mylist:
    if i == theflag:
        flagfound = True
        break
    process(i)

if not flagfound:
    raise ValueError("List argument missing terminal flag.")

In the first case the raise is bound tightly to the for loop it works with. In the second the binding is not as strong and errors may be introduced during maintenance.


回答 2

Raymond Hettinger的精彩演讲名为“ 将代码转换为美丽的惯用Python”,在其中他简要介绍了该for ... else构造的历史。相关部分是“在循环中区分多个出口点”,从15:50开始,持续大约三分钟。这里是要点:

  • for ... else结构是由Donald Knuth设计的,用于替换某些GOTO用例。
  • 重用该else关键字是有道理的,因为“这是Knuth所使用的,那时人们知道,所有[ for语句]都嵌入了an ifGOTOunder,而他们期望使用else;”。
  • 事后看来,它应该被称为“不间断”(或可能称为“不间断”),这样就不会造成混淆。*

因此,如果问题是“他们为什么不更改此关键字?” 那么Cat Plus Plus可能给出了最准确的答案 –在这一点上,它对现有代码的破坏性太大,无法实用。但是,如果您真正要问的问题是为什么else首先要重用,那么显然在当时看来是个好主意。

就个人而言,我喜欢# no break在线注释的妥协之else处,因为它们一眼就可能被误认为属于循环内。相当清晰简洁。Bjorn在回答结束时链接的摘要中简要提及了该选项:

为了完整起见,我应该提到的是,语法稍有变化,想要这种语法的程序员现在可以使用它:

for item in sequence:
    process(item)
else:  # no break
    suite

*视频那部分的奖励语录:“就像我们调用lambda makefunction一样,没人会问’lambda做什么?’”

There’s an excellent presentation by Raymond Hettinger, titled Transforming Code into Beautiful, Idiomatic Python, in which he briefly addresses the history of the for ... else construct. The relevant section is “Distinguishing multiple exit points in loops” starting at 15:50 and continuing for about three minutes. Here are the high points:

  • The for ... else construct was devised by Donald Knuth as a replacement for certain GOTO use cases;
  • Reusing the else keyword made sense because “it’s what Knuth used, and people knew, at that time, all [for statements] had embedded an if and GOTO underneath, and they expected the else;”
  • In hindsight, it should have been called “no break” (or possibly “nobreak”), and then it wouldn’t be confusing.*

So, if the question is, “Why don’t they change this keyword?” then Cat Plus Plus probably gave the most accurate answer – at this point, it would be too destructive to existing code to be practical. But if the question you’re really asking is why else was reused in the first place, well, apparently it seemed like a good idea at the time.

Personally, I like the compromise of commenting # no break in-line wherever the else could be mistaken, at a glance, as belonging inside the loop. It’s reasonably clear and concise. This option gets a brief mention in the summary that Bjorn linked at the end of his answer:

For completeness, I should mention that with a slight change in syntax, programmers who want this syntax can have it right now:

for item in sequence:
    process(item)
else:  # no break
    suite

* Bonus quote from that part of the video: “Just like if we called lambda makefunction, nobody would ask, ‘What does lambda do?'”


回答 3

因为他们不想在语言中引入新的关键字。每个人都窃取一个标识符并引起向后兼容性问题,因此通常是最后的选择。

Because they didn’t want to introduce a new keyword to the language. Each one steals an identifier and causes backwards compatibility problems, so it’s usually a last resort.


回答 4

简单起见,您可以这样想:

  • 如果breakfor循环中遇到命令,else则不会调用该部件。
  • 如果breakfor循环中未遇到该命令,else则将调用该部件。

换句话说,如果for循环迭代未被破坏breakelse则将调用该部分。

To make it simple, you can think of it like that;

  • If it encounters the break command in the for loop, the else part will not be called.
  • If it does not encounter the break command in the for loop, the else part will be called.

In other words, if for loop iteration is not “broken” with break, the else part will be called.


回答 5

我发现“了解” for / else所做的事情,最重要的是,何时使用它,最简单的方法是专注于break语句跳转到的位置。For / else构造是单个块。中断从块中跳出,因此跳过“ else”子句。如果else子句的内容仅位于for子句之后,则它将永远不会被跳过,因此必须通过将其放在if中来提供等效的逻辑。之前已经说过,但用这些话还不够,所以可能会对其他人有所帮助。尝试运行以下代码片段。为了澄清,我全心全意地赞成“不间断”的评论。

for a in range(3):
    print(a)
    if a==4: # change value to force break or not
        break
else: #no break  +10 for whoever thought of this decoration
    print('for completed OK')

print('statement after for loop')

The easiest way I found to ‘get’ what the for/else did, and more importantly, when to use it, was to concentrate on where the break statement jumps to. The For/else construct is a single block. The break jumps out of the block, and so jumps ‘over’ the else clause. If the contents of the else clause simply followed the for clause, it would never be jumped over, and so the equivalent logic would have to be provided by putting it in an if. This has been said before, but not quite in these words, so it may help somebody else. Try running the following code fragment. I’m wholeheartedly in favour of the ‘no break’ comment for clarity.

for a in range(3):
    print(a)
    if a==4: # change value to force break or not
        break
else: #no break  +10 for whoever thought of this decoration
    print('for completed OK')

print('statement after for loop')

回答 6

我认为文档对其他方面有很好的解释 ,请继续

[…]当循环通过用尽列表而终止(使用for)或条件变为假(使用while)时执行,但在循环由break语句终止时则不执行。”

来源:Python 2文档:控制流教程

I think documentation has a great explanation of else, continue

[…] it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement.”

Source: Python 2 docs: Tutorial on control flow


回答 7

我读到类似:

如果仍然有运行循环的条件,则执行其他操作,否则执行其他操作。

I read it something like:

If still on the conditions to run the loop, do stuff, else do something else.


回答 8

由于已经回答了很多技术方面的问题,因此我的评论仅与产生此回收关键字的混乱有关。

作为Python是一种非常有说服力的编程语言,关键字的滥用更为臭名昭著。该else关键字恰如其分地描述决策树的流程的一部分,“如果你不能做到这一点,(否则)做到这一点。” 它是用我们自己的语言暗示的

相反,将此关键字与whileand for语句一起使用会引起混淆。原因是,我们作为程序员的职业使我们知道该else语句位于决策树之内。它的逻辑范围,一个有条件地返回要遵循的路径的包装器。同时,循环语句具有比喻明确的目标。在流程的不断迭代之后,可以达到目标。

if / else 指明可以遵循的道路。循环遵循一条路径,直到“目标”完成

问题是这个else词清楚地定义了条件中的最后一个选项。这个词的语义由Python和人类语言共享。但是,人类语言中的else词永远不会用来表示某人或某事在完成某件事后将要采取的行动。如果在完成过程中出现问题(更像是休息),则将使用它语句)。

最后,关键字将保留在Python中。显然,这是错误的,当每个程序员尝试提出一个故事来理解其用法(如某种助记符设备)时,这一点就更加清楚。如果他们选择了关键字,我会很喜欢的then。我相信这个关键字非常适合迭代流程,即循环后的收益

这类似于某些孩子在按照每个步骤组装玩具后所遇到的情况:那么,爸爸是什么?

Since the technical part has been pretty much answered, my comment is just in relation with the confusion that produce this recycled keyword.

Being Python a very eloquent programming language, the misuse of a keyword is more notorious. The else keyword perfectly describes part of the flow of a decision tree, “if you can’t do this, (else) do that”. It’s implied in our own language.

Instead, using this keyword with while and for statements creates confusion. The reason, our career as programmers has taught us that the else statement resides within a decision tree; its logical scope, a wrapper that conditionally return a path to follow. Meanwhile, loop statements have a figurative explicit goal to reach something. The goal is met after continuous iterations of a process.

if / else indicate a path to follow. Loops follow a path until the “goal” is completed.

The issue is that else is a word that clearly define the last option in a condition. The semantics of the word are both shared by Python and Human Language. But the else word in Human Language is never used to indicate the actions someone or something will take after something is completed. It will be used if, in the process of completing it, an issue rises (more like a break statement).

At the end, the keyword will remain in Python. It’s clear it was mistake, clearer when every programmer tries to come up with a story to understand its usage like some mnemonic device. I’d have loved if they have chosen instead the keyword then. I believe that this keyword fits perfectly in that iterative flow, the payoff after the loop.

It resembles that situation that some child has after following every step in assembling a toy: And THEN what Dad?


回答 9

我将其读为“当iterable完全耗尽时,执行将在完成完成后继续执行下for一条语句,否则将执行else子句。” 因此,当迭代被中断时break,将不会执行。

I read it like “When the iterable is exhausted completely, and the execution is about to proceed to the next statement after finishing the for, the else clause will be executed.” Thus, when the iteration is broken by break, this will not be executed.


回答 10

我同意,它更像是“不是[[条件]打破休息条件]”。

我知道这是一个老话题,但是我现在正在研究相同的问题,而且我不确定有人以我理解的方式抓住了这个问题的答案。

对我来说,有三种“读取” elsein For... elseWhile... else语句的方法,所有这些方法都是等效的:

  1. else == if the loop completes normally (without a break or error)
  2. else == if the loop does not encounter a break
  3. else == else not (condition raising break) (大概有这种情况,否则您将不会循环)

因此,从本质上讲,循环中的“ else”实际上是一个“ elif …”,其中“ …”是(1)不间断,相当于(2)NOT [引起中断的条件]。

我认为关键是else没有’break’就没有意义,因此a for...else包括:

for:
    do stuff
    conditional break # implied by else
else not break:
    do more stuff

因此,for...else循环的基本元素如下,您将以普通英语阅读它们:

for:
    do stuff
    condition:
        break
else: # read as "else not break" or "else not condition"
    do more stuff

正如其他张贴者所说的那样,当您能够找到循环要查找的内容时,通常会出现中断,因此else:变成“如果未找到目标项目该怎么办”。

您还可以一起使用异常处理,中断和for循环。

for x in range(0,3):
    print("x: {}".format(x))
    if x == 2:
        try:
            raise AssertionError("ASSERTION ERROR: x is {}".format(x))
        except:
            print(AssertionError("ASSERTION ERROR: x is {}".format(x)))
            break
else:
    print("X loop complete without error")

结果

x: 0
x: 1
x: 2
ASSERTION ERROR: x is 2
----------
# loop not completed (hit break), so else didn't run

一个简单的例子,打破休息。

for y in range(0,3):
    print("y: {}".format(y))
    if y == 2: # will be executed
        print("BREAK: y is {}\n----------".format(y))
        break
else: # not executed because break is hit
    print("y_loop completed without break----------\n")

结果

y: 0
y: 1
y: 2
BREAK: y is 2
----------
# loop not completed (hit break), so else didn't run

一个简单的示例,其中没有中断,没有引发中断的条件,也没有遇到错误。

for z in range(0,3):
     print("z: {}".format(z))
     if z == 4: # will not be executed
         print("BREAK: z is {}\n".format(y))
         break
     if z == 4: # will not be executed
         raise AssertionError("ASSERTION ERROR: x is {}".format(x))
else:
     print("z_loop complete without break or error\n----------\n")

结果

z: 0
z: 1
z: 2
z_loop complete without break or error
----------

I agree, it’s more like an ‘elif not [condition(s) raising break]’.

I know this is an old thread, but I am looking into the same question right now, and I’m not sure anyone has captured the answer to this question in the way I understand it.

For me, there are three ways of “reading” the else in For... else or While... else statements, all of which are equivalent, are:

  1. else == if the loop completes normally (without a break or error)
  2. else == if the loop does not encounter a break
  3. else == else not (condition raising break) (presumably there is such a condition, or you wouldn’t have a loop)

So, essentially, the “else” in a loop is really an “elif …” where ‘…’ is (1) no break, which is equivalent to (2) NOT [condition(s) raising break].

I think the key is that the else is pointless without the ‘break’, so a for...else includes:

for:
    do stuff
    conditional break # implied by else
else not break:
    do more stuff

So, essential elements of a for...else loop are as follows, and you would read them in plainer English as:

for:
    do stuff
    condition:
        break
else: # read as "else not break" or "else not condition"
    do more stuff

As the other posters have said, a break is generally raised when you are able to locate what your loop is looking for, so the else: becomes “what to do if target item not located”.

Example

You can also use exception handling, breaks, and for loops all together.

for x in range(0,3):
    print("x: {}".format(x))
    if x == 2:
        try:
            raise AssertionError("ASSERTION ERROR: x is {}".format(x))
        except:
            print(AssertionError("ASSERTION ERROR: x is {}".format(x)))
            break
else:
    print("X loop complete without error")

Result

x: 0
x: 1
x: 2
ASSERTION ERROR: x is 2
----------
# loop not completed (hit break), so else didn't run

Example

Simple example with a break being hit.

for y in range(0,3):
    print("y: {}".format(y))
    if y == 2: # will be executed
        print("BREAK: y is {}\n----------".format(y))
        break
else: # not executed because break is hit
    print("y_loop completed without break----------\n")

Result

y: 0
y: 1
y: 2
BREAK: y is 2
----------
# loop not completed (hit break), so else didn't run

Example

Simple example where there no break, no condition raising a break, and no error are encountered.

for z in range(0,3):
     print("z: {}".format(z))
     if z == 4: # will not be executed
         print("BREAK: z is {}\n".format(y))
         break
     if z == 4: # will not be executed
         raise AssertionError("ASSERTION ERROR: x is {}".format(x))
else:
     print("z_loop complete without break or error\n----------\n")

Result

z: 0
z: 1
z: 2
z_loop complete without break or error
----------

回答 11

else这里,关键字可能会引起混淆,正如许多人指出的那样nobreaknotbreak是比较合适的。

为了for ... else ...逻辑上理解,请将其与try...except...else而不是进行比较if...else...,大多数python程序员都熟悉以下代码:

try:
    do_something()
except:
    print("Error happened.") # The try block threw an exception
else:
    print("Everything is find.") # The try block does things just find.

同样,可以认为break是一种特殊的Exception

for x in iterable:
    do_something(x)
except break:
    pass # Implied by Python's loop semantics
else:
    print('no break encountered')  # No break statement was encountered

区别是python隐含的except break,您无法将其写出,因此它变为:

for x in iterable:
    do_something(x)
else:
    print('no break encountered')  # No break statement was encountered

是的,我知道这种比较可能很困难并且很累,但是确实可以澄清这种混淆。

The else keyword can be confusing here, and as many people have pointed out, something like nobreak, notbreak is more appropriate.

In order to understand for ... else ... logically, compare it with try...except...else, not if...else..., most of python programmers are familiar with the following code:

try:
    do_something()
except:
    print("Error happened.") # The try block threw an exception
else:
    print("Everything is find.") # The try block does things just find.

Similarly, think of break as a special kind of Exception:

for x in iterable:
    do_something(x)
except break:
    pass # Implied by Python's loop semantics
else:
    print('no break encountered')  # No break statement was encountered

The difference is python implies except break and you can not write it out, so it becomes:

for x in iterable:
    do_something(x)
else:
    print('no break encountered')  # No break statement was encountered

Yes, I know this comparison can be difficult and tiresome, but it does clarify the confusion.


回答 12

elsefor不中断循环时,将执行语句块中的代码。

for x in xrange(1,5):
    if x == 5:
        print 'find 5'
        break
else:
    print 'can not find 5!'
#can not find 5!

文档:中断并继续执行语句,否则循环中的子句

循环语句可以包含else子句;当循环通过用尽列表而终止(使用for)或条件变为假(使用while)时,将执行此命令,但当循环由break语句终止时,则不会执行该命令。以下循环示例搜索质数:

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

(是的,这是正确的代码。仔细观察:else子句属于for循环,而不是if语句。)

与循环一起使用时,else子句与try语句的else子句比if语句具有更多的共同点:try语句的else子句在没有异常发生时运行,而循环的else子句在没有中断时发生运行。有关try语句和异常的更多信息,请参见处理异常。

也从C借用的continue语句继续循环的下一个迭代:

>>> for num in range(2, 10):
...     if num % 2 == 0:
...         print("Found an even number", num)
...         continue
...     print("Found a number", num)
Found an even number 2
Found a number 3
Found an even number 4
Found a number 5
Found an even number 6
Found a number 7
Found an even number 8
Found a number 9

Codes in else statement block will be executed when the for loop was not be broke.

for x in xrange(1,5):
    if x == 5:
        print 'find 5'
        break
else:
    print 'can not find 5!'
#can not find 5!

From the docs: break and continue Statements, and else Clauses on Loops

Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement. This is exemplified by the following loop, which searches for prime numbers:

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

(Yes, this is the correct code. Look closely: the else clause belongs to the for loop, not the if statement.)

When used with a loop, the else clause has more in common with the else clause of a try statement than it does that of if statements: a try statement’s else clause runs when no exception occurs, and a loop’s else clause runs when no break occurs. For more on the try statement and exceptions, see Handling Exceptions.

The continue statement, also borrowed from C, continues with the next iteration of the loop:

>>> for num in range(2, 10):
...     if num % 2 == 0:
...         print("Found an even number", num)
...         continue
...     print("Found a number", num)
Found an even number 2
Found a number 3
Found an even number 4
Found a number 5
Found an even number 6
Found a number 7
Found an even number 8
Found a number 9

回答 13

这是一种我上面没有见过其他人提到的思考方式:

首先,请记住,for循环基本上只是while循环周围的语法糖。例如循环

for item in sequence:
    do_something(item)

可以(近似)重写为

item = None
while sequence.hasnext():
    item = sequence.next()
    do_something(item)

其次,请记住,while循环基本上只是重复的if块!您始终可以将while循环读为“如果满足此条件,则执行主体,然后返回并再次检查”。

因此,while / else完全有道理:它与if / else完全相同,具有附加的循环功能,直到条件变为false为止,而不仅仅是检查条件一次。

然后for / else也很有意义:由于所有for循环只是while循环之上的语法糖,您只需要弄清楚底层while循环的隐式条件是什么,然后else对应于何时条件变为False。

Here’s a way to think about it that I haven’t seen anyone else mention above:

First, remember that for-loops are basically just syntactic sugar around while-loops. For example, the loop

for item in sequence:
    do_something(item)

can be rewritten (approximately) as

item = None
while sequence.hasnext():
    item = sequence.next()
    do_something(item)

Second, remember that while-loops are basically just repeated if-blocks! You can always read a while-loop as “if this condition is true, execute the body, then come back and check again”.

So while/else makes perfect sense: It’s the exact same structure as if/else, with the added functionality of looping until the condition becomes false instead of just checking the condition once.

And then for/else makes perfect sense too: because all for-loops are just syntactic sugar on top of while-loops, you just need to figure out what the underlying while-loop’s implicit conditional is, and then the else corresponds to when that condition becomes False.


回答 14

很好的答案是:

  • 可以解释历史,并且
  • 这样可以正确引用,以简化您的翻译/理解。

我在这里的注释来自Donald Knuth曾经说过的(抱歉无法找到参考),其中有一个while-else与if-else不能区分的构造,即(在Python中):

x = 2
while x > 3:
    print("foo")
    break
else:
    print("boo")

具有与以下相同的流量(不包括低级别差异):

x = 2
if x > 3:
    print("foo")
else:
    print("boo")

关键是,if-else可以被视为while-else的语法糖,而while-else break在其if块的末尾具有隐含的含义。相反的含义是,while循环是对的扩展if,这是更常见的(只是重复/循环条件检查),因为if通常在之前进行过讲授while。但是,这是不正确的,因为这意味着每次条件为false时else都会执行while-else块。

为了简化您的理解,请考虑以下方式:

如果不使用breakreturn等,则循环仅在条件不再为真时结束,并且在这种情况下,else块也将执行一次。如果是Python for,则必须考虑C型for循环(有条件)或将其转换为while

另一个注意事项:

过早breakreturn等内部循环,使不可能的条件,成为虚假的,因为执行跃升循环出来,而条件是真实的,它永远不会回来再检查一遍。

Great answers are:

  • this which explain the history, and
  • this gives the right citation to ease yours translation/understanding.

My note here comes from what Donald Knuth once said (sorry can’t find reference) that there is a construct where while-else is indistinguishable from if-else, namely (in Python):

x = 2
while x > 3:
    print("foo")
    break
else:
    print("boo")

has the same flow (excluding low level differences) as:

x = 2
if x > 3:
    print("foo")
else:
    print("boo")

The point is that if-else can be considered as syntactic sugar for while-else which has implicit break at the end of its if block. The opposite implication, that while loop is extension to if, is more common (it’s just repeated/looped conditional check), because if is often taught before while. However that isn’t true because that would mean else block in while-else would be executed each time when condition is false.

To ease your understanding think of it that way:

Without break, return, etc., loop ends only when condition is no longer true and in such case else block will also execute once. In case of Python for you must consider C-style for loops (with conditions) or translate them to while.

Another note:

Premature break, return, etc. inside loop makes impossible for condition to become false because execution jumped out of the loop while condition was true and it would never come back to check it again.


回答 15

您可以将其想像为 else其余内容或其他内容中未在循环中完成的。

You could think of it like, else as in the rest of the stuff, or the other stuff, that wasn’t done in the loop.


回答 16

for i in range(3):
    print(i)

    if i == 2:
        print("Too big - I'm giving up!")
        break;
else:
    print("Completed successfully")

“ else”在这里非常简单,只是意味着

1,“如果for clause完成”

for i in range(3):
    print(i)

    if i == 2:
        print("Too big - I'm giving up!")
        break;
if "for clause is completed":
    print("Completed successfully")

想要写“ for子句已完成”这样的长语句,所以要引入“ else”。

else 这本质上是一种假设。

2,但是,怎么样 for clause is not run at all

In [331]: for i in range(0):
     ...:     print(i)
     ...: 
     ...:     if i == 9:
     ...:         print("Too big - I'm giving up!")
     ...:         break
     ...: else:
     ...:     print("Completed successfully")
     ...:     
Completed successfully

因此,完全可以说是逻辑组合:

if "for clause is completed" or "not run at all":
     do else stuff

或这样说:

if "for clause is not partially run":
    do else stuff

或者这样:

if "for clause not encounter a break":
    do else stuff
for i in range(3):
    print(i)

    if i == 2:
        print("Too big - I'm giving up!")
        break;
else:
    print("Completed successfully")

“else” here is crazily simple, just mean

1, “if for clause is completed”

for i in range(3):
    print(i)

    if i == 2:
        print("Too big - I'm giving up!")
        break;
if "for clause is completed":
    print("Completed successfully")

It’s wielding to write such long statements as “for clause is completed”, so they introduce “else”.

else here is a if in its nature.

2, However, How about for clause is not run at all

In [331]: for i in range(0):
     ...:     print(i)
     ...: 
     ...:     if i == 9:
     ...:         print("Too big - I'm giving up!")
     ...:         break
     ...: else:
     ...:     print("Completed successfully")
     ...:     
Completed successfully

So it’s completely statement is logic combination:

if "for clause is completed" or "not run at all":
     do else stuff

or put it this way:

if "for clause is not partially run":
    do else stuff

or this way:

if "for clause not encounter a break":
    do else stuff

回答 17

除了搜索之外,这是另一个惯用例。假设您要等待条件为真,例如,要在远程服务器上打开端口以及一些超时。然后,您可以利用这样的while...else构造:

import socket
import time

sock = socket.socket()
timeout = time.time() + 15
while time.time() < timeout:
    if sock.connect_ex(('127.0.0.1', 80)) is 0:
        print('Port is open now!')
        break
    print('Still waiting...')
else:
    raise TimeoutError()

Here’s another idiomatic use case besides searching. Let’s say you wanted to wait for a condition to be true, e.g. a port to be open on a remote server, along with some timeout. Then you could utilize a while...else construct like so:

import socket
import time

sock = socket.socket()
timeout = time.time() + 15
while time.time() < timeout:
    if sock.connect_ex(('127.0.0.1', 80)) is 0:
        print('Port is open now!')
        break
    print('Still waiting...')
else:
    raise TimeoutError()

回答 18

我只是想自己重新理解它。我发现以下帮助!

•将else视为与if循环内部配对(而不是与for)配对-如果满足条件,则打破循环,否则执行此操作-除非它else与多个ifs 配对!
•如果根本if不满意,请执行else
•多重ifS可实际上也被认为是ifelifs ^!

I was just trying to make sense of it again myself. I found that the following helps!

• Think of the else as being paired with the if inside the loop (instead of with the for) – if condition is met then break the loop, else do this – except it’s one else paired with multiple ifs!
• If no ifs were satisfied at all, then do the else.
• The multiple ifs can also actually be thought of as ifelifs!


回答 19

我认为结构为(如果)在其他B,以及(如果)-else是一个特殊的if-else粗略。可能有助于了解其他

A和B最多执行一次,这与if-else结构相同。

for(if)可以认为是特殊的if,它会循环执行以尝试满足if条件。一旦满足if条件,则A 中断否则,B.

I consider the structure as for (if) A else B, and for(if)-else is a special if-else, roughly. It may help to understand else.

A and B is executed at most once, which is the same as if-else structure.

for(if) can be considered as a special if, which does a loop to try to meet the if condition. Once the if condition is met, A and break; Else, B.


回答 20

Python在for和while循环之后使用else循环,因此,如果没有任何内容适用于循环,则会发生其他情况。例如:

test = 3
while test == 4:
     print("Hello")
else:
     print("Hi")

输出将是一遍又一遍的“ Hi”(如果我是对的)。

Python uses an else after for and while loops so that if nothing applies to the loop, something else happens. For example:

test = 3
while test == 4:
     print("Hello")
else:
     print("Hi")

The output would be ‘Hi’ over and over again (if I’m correct).


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。