第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正 ...
随机推荐
- 非阻塞socket中read、write返回值
read返回值 >0 读取数据的长度 =0 接收到对端发送的FIN,表示对端的写端关闭. <0 如果errno=EINTR.收到信号并从信号处理函数返回时,慢系统调用会返回并设 ...
- iconfont的简单使用
下载-阿里巴巴矢量图标 网站链接:http://www.iconfont.cn/ 首页如下: 首页-进入图标库--所有图标--搜索/点击你想要的图标--添加购物车 点击购物车(下载) 如下图: 点击下 ...
- html禁止图片拖拽移动在新窗口打开
一直觉得直接从网站的表格上复制数据挺方便的, 今天,领导突然说网站上的图片可以被别人拖走了,必须禁止,哎,果然只有领导才考虑得到这种事情啊 so, 将ondragstart="return ...
- nginx限速
nginx 要实现限速,完整的实现是要限制客户端请求频率,并发连接和传输速度 1.请求限制 Nginx 请求限制的功能来自于 ngx_http_limit_req_module 模块.使用它需要首先在 ...
- Dual Camera Info
一个摄像头解决不了的问题,那就用两个:对于双摄你需要了解这些 http://www.chengshiluntan.com/wg/a/20160715/6ca0343f59789235c9419887f ...
- java中高级写法
1.低级写法: if (null != redisCacheService.get(MediaConstants.GUANGDIANTONG_YOUMI + CommonConstants.PLUS ...
- Jquery 中Ajax使用的四种情况
<script type="text/javascript" language="javascript" src="JS/jquery-1[1] ...
- Android学生管理系统
现在要做这么一个小的demo,可以添加.展示,并且在添加完了之后刷新列表内容. 要点: 在代码中给线性布局添加View 让控件滚动,放到ScrollView中 保存数据就是把数据保存到本地,然后恢复的 ...
- spring boot集成activemq
spring boot集成activemq 转自:https://blog.csdn.net/maiyikai/article/details/77199300
- android 软键盘监听显示和隐藏
githup中找到:https://github.com/yescpu/KeyboardChangeListener import android.app.Activity; import andro ...