核心知识点:

(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. 【BIEE】10_资料库查看数据报错

    导入元数据后,在资料库右键物理表名,[查看数据]报错: 出现这个问题,没搞明白是为啥- 后来百度意外发现一个方法,修改NQSConfig.INI文件即可解决问题 那么就开始来搞定这个问题 [1]打开路 ...

  2. 【Linux】使用xshell登陆时密码框为灰色,无法输入密码

    使用xshell登陆时,出现以上情况,那么这到底值咋回事呢?经过查询以后发现是服务器端设置问题,解决办法如下: vi /etc/ssh/sshd_config 接着保存退出,然后重启sshd服务 se ...

  3. Delphi Math里的基本函数,以及浮点数比较函数

    Delphi里的好东西太多,多到让人觉得烦.这种感觉就是当年打游戏<英雄无敌3>,改了钱以后,有钱了每天都要造建筑,明明是好事,可是让人觉得烦. 先记录下来,以后再回来加强对Math单元的 ...

  4. IBM Rational AppScan使用详细说明

    转自:http://www.nxadmin.com/tools/675.html 本文将详细介绍Appscan功能选项设置的细节,适合E文一般,初次接触Appscan的童鞋参考阅读. Appscan是 ...

  5. sqlserver修改表主键自增

    alter table tname add id int  identity(1,1)

  6. 千万级的大表!MySQL这样优化更好

    对于一个千万级的大表,现在可能更多的是亿级数据量,很多人第一反应是各种切分,可结果总是事半功倍,或许正是我们优化顺序的不正确.下面我们来谈谈怎样的优化顺序可以让效果更好. MySQL数据库一般都是按照 ...

  7. xml初学简单介绍

    什么是XML? 1.全称Extensible Markup Language,可扩展标记语言,W3C组织公布. 2.XML用来保存有一定结构关系的数据. 3.标签的嵌套,实质是一串字符串. 4.跨平台 ...

  8. elk文件

    =================正则匹配 [root@web02 conf.d]# cat apache-grok.conf input{ file { path => "/var/ ...

  9. [ACM] POJ 3740 Easy Finding (DLX模板题)

    Easy Finding Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16178   Accepted: 4343 Des ...

  10. TSharding源码阅读-MapperShardingInitializer

    /** * 增强Mapper处理总入口:Mapper被mybatis初始化后,在这里做进一步的处理和增强 * * @author qigong on 5/1/15 */ public class Ma ...