不要在for与while循环后面写else块

简介: 不要在for与while循环后面写else块

Python的循环有一项大多数编程语言都不支持的特性,即可以把else块紧跟在整个循环结构的后面。

for i in range(3):
    print('loop', i)
else:
    print('Else block!')

>>>>
loop 0
loop 1
loop 2
Else block!

奇怪的是,程序做完整个for循环之后,竟然会执行else块里的内容。既然是这样,那为什么要叫“else“呢?这应该叫”and“才对。在if/else结构里,else的意思是:如果没有执行前面那块语句,那就执行else块。在try/except结构里,except也是这个意思:如果前面那块语句执行失败,那就执行except块。
try/except/else结构里的else依然遵循这样的理念,它的意思是:如果没有异常需要处理,那就执行这块语句。try/finally结构里的finally同样很直观,意思是:不管前面那块代码执行得如何,最后都要执行finally块代码。
了解了else、except、finally等在上面那些结构里的用法,Python新手可能觉得,for/else结构里的else也是这个意思,即如果循环没有从头到尾执行完,那就执行else块。实际上恰恰相反,如果循环没有从头到尾执行完(也就是循环提前终止了),那么else块里的代码是不会执行的。在循环中使用break语句实际上会跳过else块。

for i in range(3):
    print('loop', i)
    if i == 1:
        break
else:
    print('Else block!')


>>>
loop 0
loop 1

还有一个奇怪的地方是,如果对空白序列做for循环,那么程序立刻就会执行else块。

for x in []:
    print('Never runs')
else:
    print('For Else block!')


>>>
For Else block!

while循环也是这样,如果首次循环就遇到False,那么程序也会立刻运行else块。

while False:
    print('Never runs')

else:
    print('While Else block!')


>>>
While Else block!

把else设计成这样,是想让你利用它实现搜索逻辑。例如,如果要判断两个数是否互质(也就是除了1之外,是不是没有别的数能够同时整除它们),就可以用这种结构实现。先把有可能同时整除它们的数逐个试一遍,如果全都试过之后还是没找到这样的数,那么循环就会从头到尾执行完(这意味着循环没有因为break而提前跳出),然后程序就会执行else块里的代码。

for i in range(2, min(a, b) + 1):
    print('Testing', i)
    if a % i == 0 and b % i == 0:
        print('Not coprime')
        break
else:
    print('Coprime')

>>>
Testing 2
Testing 3
Testing 4
Coprime

实际工作中,不会这么写,而是改用辅助函数完成计算。这样的辅助函数有两种常见的写法。
第一种写法是,只要发现某个条件成立,就立刻返回,如果始终都没碰到这种情况,那么循环就会完整地执行,让程序返回函数末尾的那个值作为默认返回值。

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

assert coprime(4, 9)
assert not coprime(3, 6)

第二种写法,用变量来记录循环过程中有没有碰到这样的情况,如果有,那就用break提前跳出循环,如果没有,循环就会完整地之行,无论如何,最后都返回这个变量的值。

def coprime_alternate(a, b):
    is_coprime = True
    for i in range(2, min(a, b) + 1):
        if a % i == 0 and b % i == 0:
            is_coprime = False
            break
    return is_coprime
assert coprime_alternate(4, 9)
assert not coprime_alternate(3, 6)

对于不熟悉for/else结构的人来说,刚才那两种写法都是比较清晰的方案,大家可以根据情况选择其中的一种。for/else或while/else结构本身虽然可以实现某些逻辑表达,但它带来的困惑,已经盖过了它的好处。因为for与while循环这种简单结构,在Python里面读起来应该相当明了才对,如果把else块紧跟在它的后面,那就会让代码产生歧义。所以,请不要这么写。

相关文章
|
2月前
什么是 While 循环?
什么是 While 循环?
80 0
|
7月前
|
算法
do while循环及练习
do while循环及练习
41 0
|
7月前
|
Java 大数据 数据处理
获取到数据循环写文件
这段代码是一个Java方法,用于分批处理数据。它定义了初始值和每批处理的数量,然后通过`PageInfo`对象获取数据。如果总数小于1,则直接返回空列表。否则,循环处理数据,防止环境中的多次空跳过,并在处理完一批数据后更新页码。代码中还提到,这个过程可以用于减少大数据操作带来的风险。此外,配有一张动图,可能表示数据处理的过程。
49 1
|
7月前
|
存储 C++ 索引
c++for结构循环超详细讲解
c++for结构循环超详细讲解
132 1
|
7月前
while循环和do while循环有什么区别
while循环和do while循环有什么区别
85 0
while循环和do while循环有什么区别?
while循环和do while循环有什么区别?
144 0
|
Oracle Java 关系型数据库
try-catch必须放在循环体外吗
try-catch必须放在循环体外吗
三个线程循环顺序打印
三个线程循环顺序打印
82 0
三个循环(C)
while语句:while(表达式){},先判断表达式,若符合,则执行循环内容,一个循环后再次判断表达式。
76 0