第12条:不要在for和while循环后面写else块
核心知识点:
(1)一般的if/else是前面不执行,后面才执行,循环下面的else是前面执行完后面才会执行,如果是break打断也不会执行。循环为空或False也不执行。
(2)try/expect是前面不执行后面才会执行,try/expect/else是try执行成功才会执行else,也就是expect不执行;try/finally不管前面是否执行后面都会执行。
(3)不要在循环后面使用else,这会让人很费解。
Python提供了一种很多编程语言都不支持的功能,那就是可以在循环内部的语句后面直接编写else。
>>> for i in range(3):
... print('Loop %d' % i)
... else:
... print('Else block!')
...
Loop 0
Loop 1
Loop 2
Else block!
奇怪的是,这种else块会在整个循环执行完之后立刻执行。既然如此,那为什么叫做else呢?为什么不叫and?
在if/else语句中,else的意思是:如果不执行前面那个if块,那就执行else块。
在try/expect语句中,expect的定义也类似:如果前面那个try块没有成功执行,那就执行expect块。
同理,try/expect/else也是如此,该结构的else含义是:如果前面的try块没有失败,那就执行else。
try/finally的意思是:执行过前面的try块之后,总是执行finally块。
明白了else、expect和finally的含义之后,刚接触Python的程序员可能会把for/else结构中的else理解为:
如果循环没有正常执行完,那就执行else块。实际上刚好相反——在循环里用break语句提前跳出,会导致程序不执行else块。
>>> for i in range(3):
... print('Loop %d' % i)
... if i == 1:
... break
... else:
... print('Else block!')
...
Loop 0
Loop 1 #没有执行else
还有一个奇怪的地方:如果for循环要遍历的序列是空的,那么就会立刻执行else块。
>>> for x in []:
... print('Never runs')
... else:
... print('For Else block!')
...
For Else block!
初始循环条件为false的while循环,如果后面跟着else,那它也会立刻执行。
>>> while False:
... print('Never runs')
... else:
... print('While Else block!')
...
While Else block!
知道了循环后面的else块所表现出的行为之后,我们会发现:在搜索某个事物的时候,这种写法是有意义的。
>>> a = 4
>>> b = 9
>>> 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
上面的式子可以判断两个数是否有除了1之外的公约数,如果有,则不会打印Compire,如果没有,就会打印Compire。
实际上,我们不会这样写代码,而是会用辅助函数来完成计算,这样的辅助函数有两种常见的写法。
第一种写法是,只要发现受测参数符合自己想要搜寻的条件,就尽早返回。如果整个循环都完整地执行了一遍,那就说明受测参数不符合要求,于是返回默认值。
>>> 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
第二种写法是,用变量来记录首测参数是否符合自己想要搜寻的条件。一旦符合,就用break跳出循环。
>>> def coprime2(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
... breake
... return is_coprime #这种方法只是上面那一种方法的升级版
对于不熟悉for/else的人来说,这两种写法都要比早前那种写法清晰很多。
for/else结构中的else块虽然也能够实现相应的功能,但是会令阅读代码的人相当不解,因为它不是属于常规逻辑。
像循环这种简单的语言结构,在python程序中应该写得非常直白才对,我们完全不应该在循环的后面使用else块
文章摘抄于Brett Slatkin的《编写高质量Python代码的59个有效方法》,仅作为个人学习使用,如有侵权请告知,将及时删除,如果觉得有益,请购买原版书籍,知识需要传递和支持,谢谢。
第12条:不要在for和while循环后面写else块的更多相关文章
- 容器使用的12条军规——《Effective+STL中文版》试读
容器使用的12条军规——<Effective+STL中文版>试读 还 记的自己早年在学校学习c++的时候,老师根本就没有讲STL,导致了自己后来跟人说 起会C++的时候总是被鄙视, ...
- [书目20160526]Brain Rules 让大脑自由:释放天赋的12条定律
推荐序1 12条定律,让大脑更聪明推荐序2 走过迷雾地带前 言 人人都有一个不可思议的大脑 定律1:越运动,大脑越聪明 信不信,“驴友”比“沙发土豆”更聪明! 老板,请把办公室的咖啡机换成跑步机! ...
- Effective Objective-C 2.0 — 第12条:理解消息转发机制
11 条讲解了对象的消息传递机制 12条讲解对象在收到无法解读的消息之后会发生什么,就会启动“消息转发”(message forwarding)机制, 若对象无法响应某个选择子,则进入消息转发流程. ...
- c#命名规范汇总12条
前言 在刚学习c#的时候,在脑子根本就么有命名规范这个概念,有了一定入门的基础,也很难严格要求自己去规范代码的命名,工作后,发现自己的命名和其他人的命名总会有一些出入,总会闹出一些尴尬的笑话,这里汇总 ...
- 盘点linux系统中的12条性能调优命令。
导读 性能调优一直是运维工程师最重要的工作之一,如果您所在的生产环境中遇到了系统响应速度慢,硬盘IO吞吐量异常,数据处理速度低于预期值的情况,又或者如CPU.内存.硬盘.网络等系统资源长期处于耗尽的状 ...
- [转]OLAP的12条准则
OLAP的12条准则 Multidimensional conceptual view OLAP模型必须提供多维概念视图 User-analysts would view an enterprise ...
- 12 条实用的 zypper 命令范例 (转载)
12 条实用的 zypper 命令范例 作者: Kerneltalks 译者: LCTT cycoe | 2018-12-12 13:29 zypper 是 Suse Linux 系统的包和补丁管理器 ...
- [转帖]12条用于Linux的MySQL/MariaDB安全最佳实践
12条用于Linux的MySQL/MariaDB安全最佳实践 2018-01-04 11:05:56作者:凉凉_,soaring稿源:开源中国社区 https://ywnz.com/linuxysjk ...
- JavaScript专业规则12条
学习JavaScript是困难的.它发展的如此之快,以至于在任何一个特定的时刻,你都不清楚自己是否“做错了”.有些时候,感觉像是坏的部分超过了好的部分.然而,讨论这些并没有意义,JavaScript正 ...
随机推荐
- Android Asynchronous Http Client 中文教程
本文为译文,原文链接https://loopj.com/android-async-http/ 安卓异步httpclient 概述 这是一个异步的基于回调的Android http客户端,构建于Apa ...
- 通知传值(NSNotificationCenter)
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenVveW91MTMxNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
- icvEvalCARTHaarClassifier
/* *icvEvalCARTHaarClassifier *作用:通过计算haar特征值,来分配非叶子节点直到出现叶子节点,最后返回输出值val. */ float icvEvalCARTHaar ...
- Chrome 完整版官方下载
Chrome下载默认不是完整版本,需要长久等等.so... 在下载地址后加参数:?standalone=1 解决问题.
- tomcat使用redis存储共享session
在tomcat集群环境下实现session共享有几种解决方式,这里介绍一种简单的方案. 使用redis对session进行存储,配置比較简单.webserver是tomcat6 1.下载jar包: c ...
- Atitit.跨语言系统服务管理器api兼容设计
Atitit.跨语言系统服务管理器api兼容设计 1. Common api,兼容sc ,service control??1 1.1. 服务创建,use sc1 1.2. 服务delete ,use ...
- Eclipse Plugin Installation and Windows User Access Control
I make Eclipse Plugins and I sell them to developers using Eclipse. Most of the visitors to my web s ...
- 【MIG专项测试组】如何准确评测Android应用的流畅度?
转自 腾讯Bugly 叶方正,2008年加入腾讯,就职于无线研发部[专项测试组].曾经负责多个产品的性能优化工作,积累大量的移动终端平台优化以及评测经验. 怎样获取SM值? 前文我们分析了通过测量应用 ...
- instagram架构分析_转
转自:http://www.eit.name/blog/read.php?504 Instagram 团队上个月才迎来第 7 名员工,是的,7个人的团队.作为 iPhone 上最火爆的图片类工具,in ...
- centos7 ACL
Linux文件权限与属性详解 之 ACL Linux文件权限与属性详解 之 一般权限Linux文件权限与属性详解 之 ACLLinux文件权限与属性详解 之 SUID.SGID & SBI ...