我理解这种结构是如何运作的:

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和continuouswith更有意义(我正试着训练自己这样读它)。

我想知道Python程序员是如何在头脑中(或者大声地,如果你喜欢)阅读这个结构的。也许我遗漏了一些可以使这些代码块更容易破译的东西?


这个问题是关于底层设计决策的,也就是说,为什么能够编写这些代码是有用的。另请参阅Python while语句中的Else子句,了解语法含义的具体问题。


当前回答

你可以这样想, 其他的东西,或者其他的东西,不是在循环中完成的。

其他回答

简单来说,你可以这样想;

如果它在for循环中遇到break命令,else部分将不会被调用。 如果在for循环中没有遇到break命令,则调用else部分。

换句话说,如果for循环迭代没有被break“打断”,else部分将被调用。

我想知道Python程序员是如何在头脑中(或者大声地,如果你喜欢)阅读这个结构的。

我只是在脑子里想:

“否则就没有中断……”

就是这样!

这是因为else子句只在for循环中没有遇到break语句时才执行。

参考:

请看这里:https://book.pythontips.com/en/latest/for_-_else.html#else-clause(强调添加,“not”改为“not”):

For循环还有一个我们大多数人都不熟悉的else子句。else子句在循环正常完成后执行。这意味着循环没有遇到break语句。


话虽如此,我还是不建议使用该语言的这个不同寻常的特性。不要在for循环之后使用else子句。这让大多数人感到困惑,并减慢了他们阅读和理解代码的能力。

我把它读成这样:“当可迭代对象完全耗尽时,在完成for语句后,执行即将继续执行下一个语句,else子句将被执行。”因此,当迭代被break打断时,这将不会执行。

很好的回答是:

这就解释了历史,而且 这就赋予了 引用以简化您的翻译/理解。

我在这里的注释来自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的语法糖,它在if块的末尾有隐含的break。相反的含义是,while循环是if的扩展,更常见(它只是重复/循环的条件检查),因为if经常在while之前教授。然而,这不是真的,因为这将意味着else块在while-else每次当condition为false时执行。

为了便于理解,可以这样想:

没有break, return等,循环只在condition不再为真时结束,在这种情况下else块也将执行一次。在Python for的情况下,你必须考虑c风格的for循环(带条件)或将它们转换为while。

另注:

循环中的过早中断、返回等使得condition不可能变为false,因为当condition为true时,执行跳出了循环,并且它永远不会再回来检查它。

一个循环的else分支只执行一次,不管这个循环是否进入它的循环体,除非循环体已经进入但没有结束。也就是说,在循环中会遇到break或return语句。

my_list = []
for i in my_list:
    print(i, end=',')
else:
    print('loop did not enter')

##################################    

for i in range(1,6,1):
    print(i, end=',')
else:
    print('loop completed successfully:', i)

##################################    

for i in range(1,6,1):
    if i == 3:
        print('loop did not finish:', i)
        break
    print(i, end=',')
else:
    print('else:', i)

输出:

loop did not enter
1,2,3,4,5,loop completed successfully: 5
1,2,loop did not finish: 3

while-else也是一样的。

import random
random.seed(8)

i = 100
while i < 90:
    print(i, end=',')
    i = random.randint(0,100)
else:
    print('loop did not enter:', i)

##################################    

i = 25
while i < 90:
    print(i, end=',')
    i = random.randint(0,100)
else:
    print('loop completed successfully:', i)

##################################    

i = 25
while i < 90:
    if i % 10 == 0:
        print('loop did not finish:', i)
        break
    print(i, end=',')
    i = random.randint(0,100)
else:
    print('else:', i)

输出:

loop did not enter: 100
25,29,47,48,16,24,loop completed successfully: 90
25,5,loop did not finish: 10