欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Python】你还在看到for循环后写else后,大呼【卧槽,牛逼!】【卧槽,还能这样?】吗?

程序员文章站 2024-01-05 15:27:34
...

摘自书籍 Effective Python

Python 有种特殊语法是很多编程语言都不支持的,可以在for及while循环的内部语句快之后紧跟一个else块。

for i in range(3):
    print("Loop {}".format(i))
else:
    print("Else Block!")

# Loop 0
# Loop 1
# Loop 2
# Else Block!

这种else块会在整个循环正常结束后立刻执行。既然如此,为什么它叫做else,而不是and呢?在if/else语句中,else的意思是:如果不执行前面的if块,那就执行else块。在try/except语句中,except的定义也类似:如果前面的try块没有执行成功,那就执行except块。

同for/else一样的道理,try/except/else也是如此,该结构的else的含义是:如果前面的try块没有失败,就执行else块。try/finally同样非常直观,这里的finally的意思是,不论try有没有正常执行,最终都要执行finally块。

明白了else,except,finally的含义之后,刚接触Python的程序员或没有了解过for/else结构的程序员可能会把for/else结构中的else理解为:如果循环没有正常执行完(这里说的正常执行完是指没有break跳出情况,而非一些异常),那就执行else块。实际上刚好相反——在循环里用break语句提前跳出,会导致程序不执行else块,就像下面的例子:

for i in range(3):
    print("Loop {}".format(i))
    if i == 1:
        break
else:
    print("Else Block!")

# Loop 0
# Loop 1

还有,如果for循环要遍历的序列是空的,那么就会立刻执行else块:

for i in []:
    print("Never Runs")
else:
    print("Else Block!")

# Else Block!

初始循环条件为false的while循环,如果后面跟着else块,那么它也会立刻执行:

while False:
    print("Never Runs")
else:
    print("Else Block!")

# Else Block!

  知道了循环后面的else块所表现出的行为后,我们会发现:在搜索某个事物的时候,这种 for/else 或 while/else 结构的写法是有意义的。比如,要判断两个数是否互质(也就是判断两者除了1之外,是否没有其他的公约数),可以把有可能成为公约数的每个值都遍历一遍,逐个判断两束时候能以该值为公约数,尝试完每一种可能的值后,循环就结束了。如果两个数确实互质,那么在循环过程中,程序就不会因break语句而跳出,于是,执行完循环后,程序会紧接着执行else块。

num1 = 4
num2 = 9
for i in range(2, min(num1, num2) + 1):
    print("Testing", i)
    if num1 % i == 0 and num2 % i == 0:
        print("Not coprime")
        break
else:
    print("Coprime")

# Testing 2
# Testing 3
# Testing 4
# Coprime

事实上,我们不会这么写代码,而是使用辅助函数来完成计算,比如,只要发现受测参数符合自己想要搜索的条件,就尽早返回。如果整个循环都执行了一遍,那就说明,受测参数不符合条件,于是返回默认值。

def coprime(num1, num2):
    for i in range(2, min(num1, num2) + 1):
        if num1 % i == 0 and num2 % i == 0:
            return False
    return True

或者,用变量记录受测参数是否符合条件,一旦符合,就用break跳出循环。

def coprime(num1, num2):
    is_coprime = True
    for i in range(2, min(num1, num2) + 1):
        if num1 % i == 0 and num2 % i == 0:
            is_coprime = False
            break
    return is_coprime

对不熟悉 for/else 的人来说,后面这两种写法都要比 for/else 的写法清晰很多。for/else 中的else块确实能实现相应的功能,但捡来回顾这段程序的时候,却会令阅读代码的人(包括写代码的人)感到相当费解。像循环这种简单的语言结构,在Python中应当写的相当直白才对,别整那些花里胡哨的,也许只有你自己觉得 for/else 看起来高大上,这可不算炫技。所以,我们完全不应该在循环后使用else块。


  • Python 提供了这种特殊语法,在for 或者 while 循环的内部语句块之后紧跟着 else 块。
  • 只有当整个循环主体没有遇到break语句时,循环后的else块才会执行。
  • 不要在循环后使用else块,因为这种写法既不直观,又容易引人误解。

上一篇:

下一篇: