Python 中被忽略的 else

来源:Python中文社区

ID:python-china

else, 我们再熟悉不过了。对于一个python程序员来说,else往往都是配合if来使用的,像这样:

a = '12'if a == '123':    print(a)else:    print('出错了!')

但是,python中的else并不只能用在if之后,so,这次我们讨论一下Python流程控制中的else。

else子句不仅能在if 语句中使用,还能在 for、while 和 try 语句中使用,这个语言特性不是什么秘密,但却没有得到重视。我们看一个例子:

my_list = ['apple', 'pear', 'orange', 'banana']for item in my_list:    if item == 'banana':        print('Founded!')        breakelse:    raise ValueError('No banana flavor found!')

本例当中,循环最后找到了'banana',输出'Founded!',并且跳出循环,所以else字句并没有被执行。但如果,将代码修改一下,去掉列表中的'banana':

my_list = ['apple', 'pear', 'orange']for item in my_list:    if item == 'banana':        print('Founded!')        breakelse:    raise ValueError('No banana flavor found!')

运行代码就会直接抛出错误!如果不使用else字句来完成上述功能,可能我们就需要设置控制标志了,像这样:

my_list = ['apple', 'pear', 'orange']flag = Truefor item in my_list:    if item == 'banana':        print('Founded!')        flag = False        breakif flag:    raise ValueError('No banana flavor found!')

很明显,这里使用了额外的变量flag和if语句。

while 和 for相类似,简单举个例子:

a = 'apple'while a == 'banana':    passelse:    raise ValueError('No banana flavor found!')

下面看一下try:

try:    dangerous_call()except OSError:    log('OSError...')else:    after_call()

很明确,try 块防守的是 dangerouscall() 可能出现的错误,而且很明显,只有 try 块不抛出异常,才会执行aftercall()。

现在,总结一下else 子句的行为如下:

for:

仅当 for 循环运行完毕时(即 for 循环没有被 break 语句中止)才运行 else 块。

while:

仅当 while 循环因为条件为假值而退出时(即 while 循环没有被break 语句中止)才运行 else 块。

try:

仅当 try 块中没有异常抛出时才运行 else 块。

即,如果异常或者 return、break 或 continue 语句导致控制权跳到了复合语句的主块之外,那么else 子句也会被跳过。

for/else、while/else 和 try/else 的语义关系紧密,不过与if/else 差别很大。主要是else 这个单词的意思阻碍了我们对这些特性的理解。 按正常的理解应该是“要么运行这个循环,要么做那件事”。可是,在循环中,else 的语义恰好相反:“运行这个循环,然后做那件事。”不过,相信多使用几次,你会熟悉的。

原文发布于微信公众号 - 马哥Linux运维(magedu-Linux)

原文发表时间:2018-05-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

Python字符编码全解析

字符编码是计算机编程中不可回避的问题,不管你用 Python2 还是 Python3,亦或是 C++, Java 等,我都觉得非常有必要厘清计算机中的字符编码概...

2676
来自专栏余林丰

1.比较排序之冒泡排序

  冒泡排序可以说是在排序算法中最为入门级别的算法之一了。因为其简单易于理解,常在课堂中作为排序的入门算法。   冒泡排序见名生意,其排序过程如同水里的泡一般由...

1706
来自专栏CaiRui

Python列表删除的三种方法

1、使用del语句删除元素 >>> i1 = ["a",'b','c','d'] >>> del i1[0] >>> print(i1) ['b', 'c',...

1798
来自专栏java学习

面试题8(如何获得数组大小)

给出语句“int[]array" 声明,并且初始化该数组,则下面哪个表达式会返回数组的大小。请选择正确的答案。 (a) array[].length() (b)...

3286
来自专栏微信公众号:Java团长

单例模式讨论篇:单例模式与垃圾回收

Jvm的垃圾回收机制到底会不会回收掉长时间不用的单例模式对象,这的确是一个比较有争议性的问题。将这一部分内容单独成篇的目的也是为了与广大博友广泛的讨论一下这个问...

982
来自专栏racaljk

[数据结构]对链表、栈、队列的总结

你应该发现了一些异常,为什么链表只有node的定义?再来细想一下这三种模型,我们会发现链表其实就是由节点组成的,而栈和队列我们把它视作一个容器,然后可以向里面放...

783
来自专栏java学习

面试题18(以下关于集合类 ArrayList 、 LinkedList 、 HashMap 描述错误的是?)

以下关于集合类 ArrayList 、 LinkedList 、 HashMap 描述错误的是? A)HashMap实现Map接口,它允许任何类型的键和值对象,...

2635
来自专栏liulun

Nim教程【六】

目前看来这是国内第一个关于Nim的系列教程 先说废话 Rust1.0已经发布了, 国内有一个人为这个事情写了一篇非常长的博客, 这篇文章我前几天草草的看了...

1896
来自专栏用户2442861的专栏

#define和typedef的用法与区别及面试问题

在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像:

1091
来自专栏趣谈编程

选择排序

面试官: 聊聊选择排序 选择排序是一种简单直观的算法,今天我们聊聊选择排序的思想,代码以及复杂度 排序思想 一天,小一尘和师傅下山去了,在集市中路经一个水果摊,...

3058

扫码关注云+社区