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

摘自书籍 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块,因为这种写法既不直观,又容易引人误解。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值