核心知识点:

(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. shell3

    例一:监控httpd是否正常运行并自动开启 #!/bin/bash port=$(nmap -sT localhost | grep 'http$' |awk '{print $2}') riqi=$ ...

  2. 自动化统一安装部署tomcat

    背景:多台服务器来回切换,安装部署tomcat,浪费时间 目的: 一次修改,统一安装,统一部署. 进程:ps -ef|grep tomcat|grep -v 'grep'|awk '{print $2 ...

  3. useradd(总结)

    useradd,一条简单的语句,会引起六个文件的变化 举例一: useradd sc 1.可以看到在最后一行,多了一个用户.cat /etc/passwd [有一个字段为X,代表还没有密码] 2.密码 ...

  4. 【DB2】db2命令Export与Import

    环境准备 1.新建表 qinys@Linux:~> db2 "create table tb1(id int,dt timestamp,name varchar(100))" ...

  5. 根域名服务器 根服务器一般指根域名服务器 (DNS)

    Why There Are Only 13 DNS Root Name Servers -------------------------------------------------------- ...

  6. Shiro学习小结

    1. What is Shiro? Apache旗下一个开源的Java权限框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权.加密.会话管理等功能,组成了一个通用的安全认证框架 ...

  7. [[NSBundle mainBundle] pathForResource:@"name" ofType:@"type"] 找不到对应的文件解决方法

    最近在使用[[NSBundle mainBundle] pathForResource:@"name" ofType:@"type"]时,找不到其对应的文件,文 ...

  8. 转: Appium ---移动自动化测试

    转自:http://www.cnblogs.com/nbkhic/p/3803830.html 什么是appium? 下面这段介绍来自于appium的官网. Appium is an open-sou ...

  9. 清除掉AD的相关属性!

    今天有朋友问我怎么清除掉AD 的相关属性,由于他们的用户都设置了登录到属性,这样我们的用户就仅仅能登陆他须要设置的计算机.对于兴许规则的变更的时候,我们的管理员配置起来就比較复杂.他须要非常长的时间去 ...

  10. webpack 使用配置

    注意:webpack 2.0版本之后有所区别 一.插件篇 1. 自动补全css3前缀 autoprefixer 官方是这样说的:Parse CSS and add vendor prefixes to ...