Python技巧:不要在for与while循环后写else块

开发 后端
本文会详细介绍一个小技巧,帮助你用符合Python风格的方式(Pythonic方式)来编写程序。

 [[385319]]

实际工作中,笔者不会这样写,而是会改用辅助函数完成计算。这样的辅助函数有两种常见的写法。

第一种写法是,只要发现某个条件成立,就立刻返回,如果始终都没碰到这种情况,那么循环就会完整地执行,让程序返回函数末尾的那个值作为默认返回值。

  1. def coprime(a, b): 
  2.     for i in range(2, min(a, b) + 1): 
  3.         if a % i == 0 and b % i == 0: 
  4.             return False 
  5.     return True 
  6.  
  7. assert coprime(4, 9) 
  8. assert not coprime(3, 6) 

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

 

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

 

对于不熟悉for/else结构的人来说,刚才那两种写法都是比较清晰的方案,大家可以根据情况选择其中的一种。

for/else或while/else结构本身虽然可以实现某些逻辑表达,但它给读者(也包括你自己)带来的困惑,已经盖过了它的好处。因为for与while循环这种简单的结构,在Python里面读起来应该相当明了才对,如果把else块紧跟在它的后面,那就会让代码产生歧义。所以,请不要这么写。

要点

  • Python有种特殊的语法,可以把else块紧跟在整个for循环或while循环的后面。
  • 只有在整个循环没有因为break提前跳出的情况下,else块才会执行。
  • 把else块紧跟在整个循环后面,会让人不太容易看出这段代码的意思,所以要避免这样写。

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

 

  1. for i in range(3): 
  2.     print('Loop', i) 
  3. else
  4.     print('Else block!'
  5. >>> 
  6. Loop 0 
  7. Loop 1 
  8. Loop 2 
  9. 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块。

 

  1. for i in range(3): 
  2.     print('Loop', i) 
  3.     if i==1: 
  4.         break 
  5. else
  6.     print('Else b1ock!'
  7. >>> 
  8. Loop 0 
  9. Loop 1 

 

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

 

  1. for x in []: 
  2.     print('Never runs'
  3. else
  4.     print('For Else block!'
  5. >>> 
  6. For Else block! 

 

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

 

  1. while False
  2.     print('Never runs'
  3. else
  4.     print('While Else block!'
  5. >>> 
  6. While Else block! 

 

把else设计成这样,是想让你利用它实现搜索逻辑。

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

 

  1. a = 4 
  2. b = 9 
  3. for i in range(2, min(a, b) + 1): 
  4.     print('Testing',i) 
  5.     if a % i == 0 and b % i == 0: 
  6.         print('Not coprime'
  7.         break 
  8. else
  9.     print('Coprime'
  10. >>> 
  11. Testing 2 
  12. Testing 3 
  13. Testing 4 
  14. Coprime 

实际工作中,笔者不会这样写,而是会改用辅助函数完成计算。这样的辅助函数有两种常见的写法。

第一种写法是,只要发现某个条件成立,就立刻返回,如果始终都没碰到这种情况,那么循环就会完整地执行,让程序返回函数末尾的那个值作为默认返回值。

  1. def coprime(a, b): 
  2.     for i in range(2, min(a, b) + 1): 
  3.         if a % i == 0 and b % i == 0: 
  4.             return False 
  5.     return True 
  6.  
  7. assert coprime(4, 9) 
  8. assert not coprime(3, 6) 

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

 

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

 

对于不熟悉for/else结构的人来说,刚才那两种写法都是比较清晰的方案,大家可以根据情况选择其中的一种。

for/else或while/else结构本身虽然可以实现某些逻辑表达,但它给读者(也包括你自己)带来的困惑,已经盖过了它的好处。因为for与while循环这种简单的结构,在Python里面读起来应该相当明了才对,如果把else块紧跟在它的后面,那就会让代码产生歧义。所以,请不要这么写。

要点

  • Python有种特殊的语法,可以把else块紧跟在整个for循环或while循环的后面。
  • 只有在整个循环没有因为break提前跳出的情况下,else块才会执行。
  • 把else块紧跟在整个循环后面,会让人不太容易看出这段代码的意思,所以要避免这样写。

 

责任编辑:华轩 来源: 今日头条
相关推荐

2018-07-16 16:29:26

编程函数代码

2022-08-10 14:36:05

Python循环函数

2013-11-27 09:16:28

编程结构

2021-01-28 09:55:50

while(1)for(;;)Linux

2021-03-17 11:16:58

while(1)for(;;)语言

2021-12-09 23:20:31

Python循环语句

2020-12-11 05:57:01

Python循环语句代码

2015-10-10 10:36:00

warning category

2021-02-25 09:35:32

语句elsePython

2021-03-24 13:17:41

编程循环语句Java

2011-01-19 12:52:49

WCF.NETC#

2023-09-27 10:19:37

类型video函数

2023-04-20 13:59:01

Pythonwhile循环的

2010-09-08 17:00:22

SQLWHILE循环

2012-09-06 09:21:22

编程语言技术

2021-12-07 11:31:47

Python代码if…elif…els

2022-01-17 21:08:54

Python 循环结构

2021-03-29 08:05:15

User项目安全

2019-04-15 14:05:56

MySQLUTF-8数据库

2014-08-04 15:30:39

Linux开源软件
点赞
收藏

51CTO技术栈公众号