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

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子句,了解语法含义的具体问题。


当前回答

因为他们不想给这门语言引入一个新的关键字。每一个都窃取一个标识符并导致向后兼容问题,所以通常是最后的手段。

其他回答

一个循环的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

由于技术部分已经回答了很多,我的评论只是与产生这个循环关键字的混淆有关。

由于Python是一种非常雄辩的编程语言,关键字的误用更加臭名昭著。else关键字完美地描述了决策树的部分流程,“如果你不能做这个,(else)做那个”。这在我们自己的语言中是隐含的。

相反,与while和for语句一起使用这个关键字会造成混淆。原因是,我们作为程序员的职业生涯告诉我们else语句存在于决策树中;它的逻辑作用域是一个有条件地返回要遵循的路径的包装器。同时,循环语句有一个象征性的明确目标来达到某些东西。目标是在流程的连续迭代之后实现的。

If / else表示要遵循的路径。循环遵循一条路径,直到“目标”完成。

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

最后,关键字将保留在Python中。很明显这是一个错误,当每个程序员都试图像记忆工具一样想出一个故事来理解它的用法时,就更清楚了。如果他们选择了关键词,我会很喜欢的。我相信这个关键字非常适合迭代流程,即循环后的收益。

这就像有些孩子组装玩具的每一步都会遇到的情况:然后呢,爸爸?

我同意,它更像是一个'elif not[条件(s)提高中断]'。

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

对我来说,有三种方法来“阅读”For…else or While…所有等价的Else语句是:

Else ==如果循环正常完成(没有中断或错误) Else ==如果循环没有遇到断点 Else == Else not(条件引发中断)(假设存在这样的条件,否则就不会有循环)

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

我认为关键在于,如果没有break, else是没有意义的,所以for…其他的包括:

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

a的基本元素。else循环如下所示,你可以用更简单的英语阅读它们:

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

正如其他帖子所说,当你能够找到你的循环正在寻找的东西时,通常会引发一个break,所以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
----------

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

我只是在脑子里想:

“否则就没有中断……”

就是这样!

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

参考:

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

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


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

因为他们不想给这门语言引入一个新的关键字。每一个都窃取一个标识符并导致向后兼容问题,所以通常是最后的手段。