核心知识点:

(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块的更多相关文章

  1. 容器使用的12条军规——《Effective+STL中文版》试读

    容器使用的12条军规——<Effective+STL中文版>试读     还 记的自己早年在学校学习c++的时候,老师根本就没有讲STL,导致了自己后来跟人说 起会C++的时候总是被鄙视, ...

  2. [书目20160526]Brain Rules 让大脑自由:释放天赋的12条定律

    推荐序1 12条定律,让大脑更聪明推荐序2 走过迷雾地带前  言 人人都有一个不可思议的大脑 定律1:越运动,大脑越聪明 信不信,“驴友”比“沙发土豆”更聪明! 老板,请把办公室的咖啡机换成跑步机! ...

  3. Effective Objective-C 2.0 — 第12条:理解消息转发机制

    11 条讲解了对象的消息传递机制 12条讲解对象在收到无法解读的消息之后会发生什么,就会启动“消息转发”(message forwarding)机制, 若对象无法响应某个选择子,则进入消息转发流程. ...

  4. c#命名规范汇总12条

    前言 在刚学习c#的时候,在脑子根本就么有命名规范这个概念,有了一定入门的基础,也很难严格要求自己去规范代码的命名,工作后,发现自己的命名和其他人的命名总会有一些出入,总会闹出一些尴尬的笑话,这里汇总 ...

  5. 盘点linux系统中的12条性能调优命令。

    导读 性能调优一直是运维工程师最重要的工作之一,如果您所在的生产环境中遇到了系统响应速度慢,硬盘IO吞吐量异常,数据处理速度低于预期值的情况,又或者如CPU.内存.硬盘.网络等系统资源长期处于耗尽的状 ...

  6. [转]OLAP的12条准则

    OLAP的12条准则 Multidimensional conceptual view OLAP模型必须提供多维概念视图 User-analysts would view an enterprise ...

  7. 12 条实用的 zypper 命令范例 (转载)

    12 条实用的 zypper 命令范例 作者: Kerneltalks 译者: LCTT cycoe | 2018-12-12 13:29 zypper 是 Suse Linux 系统的包和补丁管理器 ...

  8. [转帖]12条用于Linux的MySQL/MariaDB安全最佳实践

    12条用于Linux的MySQL/MariaDB安全最佳实践 2018-01-04 11:05:56作者:凉凉_,soaring稿源:开源中国社区 https://ywnz.com/linuxysjk ...

  9. JavaScript专业规则12条

    学习JavaScript是困难的.它发展的如此之快,以至于在任何一个特定的时刻,你都不清楚自己是否“做错了”.有些时候,感觉像是坏的部分超过了好的部分.然而,讨论这些并没有意义,JavaScript正 ...

随机推荐

  1. 非阻塞socket中read、write返回值

    read返回值 >0   读取数据的长度 =0   接收到对端发送的FIN,表示对端的写端关闭. <0   如果errno=EINTR.收到信号并从信号处理函数返回时,慢系统调用会返回并设 ...

  2. iconfont的简单使用

    下载-阿里巴巴矢量图标 网站链接:http://www.iconfont.cn/ 首页如下: 首页-进入图标库--所有图标--搜索/点击你想要的图标--添加购物车 点击购物车(下载) 如下图: 点击下 ...

  3. html禁止图片拖拽移动在新窗口打开

    一直觉得直接从网站的表格上复制数据挺方便的, 今天,领导突然说网站上的图片可以被别人拖走了,必须禁止,哎,果然只有领导才考虑得到这种事情啊 so, 将ondragstart="return ...

  4. nginx限速

    nginx 要实现限速,完整的实现是要限制客户端请求频率,并发连接和传输速度 1.请求限制 Nginx 请求限制的功能来自于 ngx_http_limit_req_module 模块.使用它需要首先在 ...

  5. Dual Camera Info

    一个摄像头解决不了的问题,那就用两个:对于双摄你需要了解这些 http://www.chengshiluntan.com/wg/a/20160715/6ca0343f59789235c9419887f ...

  6. java中高级写法

    1.低级写法: if (null != redisCacheService.get(MediaConstants.GUANGDIANTONG_YOUMI + CommonConstants.PLUS  ...

  7. Jquery 中Ajax使用的四种情况

    <script type="text/javascript" language="javascript" src="JS/jquery-1[1] ...

  8. Android学生管理系统

    现在要做这么一个小的demo,可以添加.展示,并且在添加完了之后刷新列表内容. 要点: 在代码中给线性布局添加View 让控件滚动,放到ScrollView中 保存数据就是把数据保存到本地,然后恢复的 ...

  9. spring boot集成activemq

    spring boot集成activemq 转自:https://blog.csdn.net/maiyikai/article/details/77199300

  10. android 软键盘监听显示和隐藏

    githup中找到:https://github.com/yescpu/KeyboardChangeListener import android.app.Activity; import andro ...