Python 中的 else详解


Posted in Python onApril 23, 2016

我们都知道 Python 中else的基本用法是在条件控制语句中的 if...elif...else...,但是 else 还有两个其它的用途,一是用于循环的结尾,另一个是用在错误处理的 try 中。这原本是 Python 的标准语法,但由于和大部分其它编程语言的习惯不太一样,致使人们有意或无意地忽略了这些用法。另外,对于这些用法是否符合 0×00 The Zen of Python 的原则以及该不该广泛使用也存在很多争议。例如在我看到的两本书里(Effective Python VS Write Idiomatic Python),两位作者就分别对其持有截然不同的态度。

循环中的 else

跟在循环后面的 else 语句只有在当循环内没出现 break,也就是正常循环完成时才会执行。首先我们来看一个插入排序法的例子:

from random import randrange
def insertion_sort(seq):
  if len(seq) 1:
    return seq
  _sorted = seq[:1]
  for i in seq[1:]:
    inserted = False
    for j in range(len(_sorted)):
      if i _sorted[j]:
        _sorted = [*_sorted[:j], i, *_sorted[j:]]
        inserted = True
        break
    if not inserted:
      _sorted.append(i)
  return _sorted
 
print(insertion_sort([randrange(1, 100) for i in range(10)]))

[8, 12, 12, 34, 38, 68, 72, 78, 84, 90]

在这个例子中,对已排序的 _sorted 元素逐个与 i 进行比较,若 i 比已排序的所有元素都大,则只能排在已排序列表的最后。这时我们就需要一个额外的状态变量 inserted 来标记完成遍历循环还是中途被 break,在这种情况下,我们可以用 else 来取代这一状态变量:

def insertion_sort(seq):
  if len(seq) 1:
    return seq
  _sorted = seq[:1]
  for i in seq[1:]:
    for j in range(len(_sorted)):
      if i _sorted[j]:
        _sorted = [*_sorted[:j], i, *_sorted[j:]]
        break
    else:
      _sorted.append(i)
  return _sorted
print(insertion_sort([randrange(1, 100) for i in range(10)]))

[1, 10, 27, 32, 32, 43, 50, 55, 80, 94]

我认为这是一个非常酷的做法!不过要注意的是,除了 break 可以触发后面的 else 语句,没有循环的时候也会:

while False:
  print("Will never print!")
else:
  print("Loop failed!")


Loop failed!

错误捕捉中的 else

try...except...else...finally 流程控制语法用于捕捉可能出现的异常并进行相应的处理,其中 except 用于捕捉 try 语句中出现的错误;而 else 则用于处理没有出现错误的情况;finally 负责 try 语句的”善后工作“ ,无论如何都会执行。可以通过一个简单的例子来展示:

def divide(x, y):
  try:
    result = x / y
  except ZeroDivisionError:
    print("division by 0!")
  else:
    print("result = {}".format(result))
  finally:
    print("divide finished!")
divide(5,2)
print("*"*20)
divide(5,0)

result = 2.5
divide finished!
********************
division by 0!
divide finished!

当然,也可以用状态变量的做法来替代 else:

def divide(x, y):
  result = None
  try:
    result = x / y
  except ZeroDivisionError:
    print("division by 0!")
  if result is not None:
    print("result = {}".format(result))
  print("divide finished!")
 
divide(5,2)
print("*"*20)
divide(5,0)

result = 2.5
divide finished!
********************
division by 0!
divide finished!

总结

有人觉得 else 的这些用法违反直觉或者是 implicit 而非 explicit,不值得提倡。但我觉得这种”判决“需要依赖具体的应用场景以及我们对 Python 的理解,并非一定要对新人友好的语法才算是 explicit 的。当然也不推荐在所有地方都使用这个语法,for/while...else 最大的缺点在于 else 是需要与 for/file 对齐的,如果是多层嵌套或者循环体太长的情况,就非常不适合用 else(回忆一下游标卡尺的梗就知道了:P)。只有在一些简短的循环控制语句中,我们通过 else 摆脱一些累赘的状态变量,这才是最 Pythonic 的应用场景!

Python 相关文章推荐
归纳整理Python中的控制流语句的知识点
Apr 14 Python
Python程序中的观察者模式结构编写示例
May 27 Python
Python计算斗牛游戏概率算法实例分析
Sep 26 Python
每天迁移MySQL历史数据到历史库Python脚本
Apr 13 Python
解决在pycharm中显示额外的 figure 窗口问题
Jan 15 Python
对python过滤器和lambda函数的用法详解
Jan 21 Python
python实现计数排序与桶排序实例代码
Mar 28 Python
Python OpenCV 调用摄像头并截图保存功能的实现代码
Jul 02 Python
python实现最小二乘法线性拟合
Jul 19 Python
python socket通信编程实现文件上传代码实例
Dec 14 Python
windows下python安装pip方法详解
Feb 10 Python
python打包多类型文件的操作方法
Sep 21 Python
Python 探针的实现原理
Apr 23 #Python
一键搞定python连接mysql驱动有关问题(windows版本)
Apr 23 #Python
Linux 发邮件磁盘空间监控(python)
Apr 23 #Python
web.py 十分钟创建简易博客实现代码
Apr 22 #Python
在windows下快速搭建web.py开发框架方法
Apr 22 #Python
基于python实现的抓取腾讯视频所有电影的爬虫
Apr 22 #Python
Python开发之快速搭建自动回复微信公众号功能
Apr 22 #Python
You might like
PHP中trait使用方法详细介绍
2017/05/21 PHP
PHP抽象类基本用法示例
2018/12/28 PHP
基于Jquery的表格隔行换色,移动换色,点击换色插件
2010/12/22 Javascript
基于mootools插件实现遮罩层新手引导
2012/05/24 Javascript
JQuery伸缩导航练习示例
2013/11/13 Javascript
javascript每日必学之运算符
2016/02/16 Javascript
bootstrap网页框架的使用方法
2016/05/10 Javascript
利用AngularJs实现京东首页轮播图效果
2016/09/08 Javascript
实现easyui的datagrid导出为excel的示例代码
2016/11/10 Javascript
js随机生成一个验证码
2017/06/01 Javascript
基于Vuejs和Element的注册插件的编写方法
2017/07/03 Javascript
template.js前端模板引擎使用详解
2017/10/10 Javascript
jQuery动态操作表单示例【基于table表格】
2018/12/06 jQuery
vue.js 打包时出现空白页和路径错误问题及解决方法
2019/06/26 Javascript
layui插件表单验证提交触发提交的例子
2019/09/09 Javascript
python实现的一个p2p文件传输实例
2014/06/04 Python
Python计算两个日期相差天数的方法示例
2017/05/23 Python
tensorflow实现加载mnist数据集
2018/09/08 Python
Python3获取拉勾网招聘信息的方法实例
2019/04/03 Python
Python3使用PySynth制作音乐的方法
2019/09/09 Python
Python3操作MongoDB增册改查等方法详解
2020/02/10 Python
在pycharm中为项目导入anacodna环境的操作方法
2020/02/12 Python
Python实现分数序列求和
2020/02/25 Python
Html5 Canvas实现图片标记、缩放、移动和保存历史状态功能 (附转换公式)
2020/03/18 HTML / CSS
美国新兴城市生活方式零售商:VILLA
2017/12/06 全球购物
演讲稿怎么写
2014/01/07 职场文书
回门宴新郎答谢词
2014/01/12 职场文书
数控个人求职信范文
2014/02/03 职场文书
先进党员事迹材料
2014/12/24 职场文书
企业百日安全活动总结
2015/05/07 职场文书
校长新学期致辞
2015/07/30 职场文书
KTV员工管理制度
2015/08/06 职场文书
《用字母表示数》教学反思
2016/02/17 职场文书
适合毕业生创业的项目怎么找?
2019/08/08 职场文书
五年级作文之想象作文
2019/10/30 职场文书
总结Python使用过程中的bug
2021/06/18 Python