
3.2 控制流
Python中的控制流语句和其他编程软件控制流相似,主要包含if分支、for循环和while循环,而且控制流的使用非常频繁。例如,分不同情况执行不同的内容就可以使用if分支完成;对每一个对象进行相同的操作可以使用for循环实现;当无法确定循环的对象是什么时,还可以使用while循环完成重复性的操作。下面就详细介绍if分支、for循环和while循环的具体使用说明。
3.2.1 if分支
if分支是用来判别某个条件是否满足时所对应的执行内容,常见的分支类型有二分支类型和多分支类型。二分支是指条件只有两种情况,例如年龄是否大于18周岁,收入是否超过15000元等。多分支是指条件个数超过两种,例如将考试成绩分成合格、良好和优秀三种等级,将年龄分为少年、青年、中年和老年4个段。可以将if分支形象地表示成图3-1。

图3-1 if分支流程图
如图3-1所示,菱形代表条件,矩形代表不同条件下执行的语句块。左图展示的就是二分支的情况,右图为三分支的判断风格。在Python中二分支和三分支的语法可以写成表3-1的形式。
表3-1 if分支的二分支和三分支的语法

关于上面的语法,有如下4点需要注意:
- 对于多分支的情况,else if在Python缩写为elif。
- 不论是关键词if、elif还是else,其所在的行末尾都必须加上英文状态的冒号。
- 在条件之后的执行语句(expression部分)都需要缩进,而且在整个语句块中,保持缩进风格一致。
- else关键词后面千万不要再加上具体的条件。
针对上面的语法,通过简单的例子(见表3-2)来加以说明,希望读者能够比较好地理解if分支的语法和注意事项。
表3-2 if语句二分支和多分支的例子

3.2.2 for循环
循环的目的一般都是为了解决重复性的工作,如果你需要对数据集中的每一行做相同的处理,但不使用循环的话,就会导致代码量剧增,而且都是无意义的重复代码。如果使用循环的语法解决类似上面的问题,也许只要10行左右的代码即可,既保证代码的简洁性,又保证问题得到解决。为了使读者形象地理解for循环的操作流程,可将其表示为如图3-2所示的效果。

图3-2 for循环的操作流程
如图3-2所示,对于for循环来说,就是把可迭代对象中的元素(如列表中的每一个元素)通过漏斗的小口依次倒入之后的执行语句中。在图3-2中,漏斗代表可迭代对象,小球代表可迭代对象中的元素,黑框是对每一个元素的具体计算过程,菱形是需要对每一个元素做条件判断,圆柱体则存放了计算后的结果。
对于左图来说,直接将漏斗中的每一个元素进行某种计算,最终把计算结果存储起来;右图相对复杂一些,多了一步计算前的判断,这个就需要if分支和for循环搭配完成,然后将各分支的结果进行存储。接下来,分别对如上两种for循环用法加以案例说明。

如上展示的就是对列表list6中每个元素做平方加1的结果,在for循环之前先构造了空列表result,用于最终计算结果的存储;Python中的指数运算可以使用两个星号表示,如3的5次方可以写成3**5;最后通过列表的append方法将每个元素的计算结果依次存入result变量中。下面再看一个有判断条件的for循环用法。

如上结果所示,通过for循环可以非常方便地计算出所有1到100之间的偶数和。对于上面Python语句有如下5点说明:
- 在进入循环之前必须定义一个变量,并将0赋给它,目的是用于和的累加。
- 虽然可以通过方括号[]实现列表的构建,但是手工写入1至100的数字很麻烦,如果使用Python提供的range函数就可以非常方便地生成有规律的可迭代对象,但是该函数取不到上限,所以range函数的第二个参数写入的是101。
- 判断一个数值是否为偶数,就将该数值与2相除求其余数,如果余数等于0则为偶数,否则为奇数,所以用%表示计算两个数商的余数,判断余数是否等于0,用双等号“==”表示。
- 由于计算的是偶数和,所以if分支属于二分支类型,这里只关心偶数的和,对于else部分就直接使用关键词pass表示忽略,当然读者也可以省略掉else:和pass两行。
- 最后的print输出部分使用了格式化的输出方法,如代码中的%d代表一个整数型的坑,%s1_100就是往坑中填入的值,如果有多个待填入坑,就得指定多个填入的值,这样的格式化输出可以写成%(值1,值2,值3)。除了有整数型的坑,还有%s、%f和.2f%等,分别代表字符型的坑、浮点型(小数型)的坑和保留两位小数点的浮点型坑等。
如果是对可迭代对象中的每一个元素做相同处理的话,正如上面的例子中对列表list6的每个元素做平方加1的计算,不仅可以使用for循环,还可以通过更简单的列表表达式完成。对于列表表达式,可以写成如下语法:
[expression for i in iterable if condition]
在上面的列表表达式中,expression就是对每一个元素的具体操作表达式;iterable是某个可迭代对象,如列表、元组或字符串等;if condition是对每一个元素做分支判断,如果条件符合,则expression操作对应的元素。为了更好地说明列表表达式,下面举一个示例:
# 对列表中的偶数做三次方减10的处理 list7 = [3,1,18,13,22,17,23,14,19,28,16] result = [i ** 3 - 10 for i in list7 if i % 2 == 0] print(result)
out: [5822, 10638, 2734, 21942, 4086]
如上结果所示,在原列表list7中通过余数判断获得5个偶数,分别是18、22、14、28和16,再对这些数做三次方减10的操作就得到了最终的输出结果,而且结果还是列表型的数据结构。Python中除了有列表表达式,还有元组表达式和字典表达式,它们的语法跟列表表达式类似,由于它们在实际工作中的使用并不是很频繁,所以就不对它们做详细说明了。
如果读者在学习或工作中需要解决的问题既可以用for循环实现也可以通过列表表达式完成,建议优先选择列表表达式的方法,因为其语法简洁,而且在计算的效率上也比多行的for循环高得多。关于for循环的内容就讲解这么多,最后介绍控制流中的while循环。
3.2.3 while循环
while循环与for循环有一些相似之处,有时for循环的操作和while循环的操作是可以互换的,但while循环更适合无具体迭代对象的重复性操作。这句话理解起来可能比较吃力,下面通过一个比较形象的例子来说明两者的差异。
当你登录某手机银行APP账号时,一旦输入错误,就会告知用户还剩几次输入机会,很明显,其背后的循环就是限定用户只能在N次范围内完成正确的输入,否则当天就无法再进行用户名和密码的输入,对于for循环来说,就有了具体的迭代对象,如从1到N;当你在登录某邮箱账号时,输入错误的用户名或密码,只会告知“您的用户名或密码错误”,并不会限定还有几次剩余的输入机会,所以对于这种重复性的输入操作,对方服务器不确定用户将会输入多少次才会正确,对于while循环来说,就相当于一个无限次的循环,除非用户输入正确。
首先来了解一下while循环在Python中的语法表达:
while condition: if condition1: expression1 elif condition2: expression2 else: expression3
当while关键词后面的条件满足时,将会重复执行第二行开始的所有语句块。一般情况下,while循环都会与if分支搭配使用,就像for循环与if分支搭配一样,如上面的while循环语法中就内嵌了三分支的if判断,读者可以根据具体的情况调整分支的个数。针对上文提到的两种账号登录模式,进一步通过实例(见表3-3)代码来比较for循环和while循环的操作差异。
表3-3 for循环和while的例子

对如上呈现的代码做几点解释:
- input函数可以实现人机交互式的输入,一旦运行,用户填入的任何内容都会以字符型的值赋值给user变量和password变量,由于实际的密码为数字123,因此必须将input函数的结果套在int函数内,将其转换为整数型。
- 如果有多个条件,条件之间的逻辑关系不管是“且”(用&表示)还是“或”(用|表示),所有的条件都必须用圆括号括起来,否则可能会得到诡异的结果。
- 在while循环中,while关键词后面直接跟上True值,就表示循环将无限次执行,正如用户无限次输入错误的用户名和密码一般,直到输入正确并碰见break关键词时才会退出循环。
- break关键字在Python的循环过程中会比较常见,其功能是退出离它最近的循环系统(可能是for循环或while循环)。如代码所示,当正确填入用户名和密码时,就会执行break关键字,此时就会退出整个循环系统。与break类似的另一个关键字是continue,不同的是,continue只是结束循环系统中的当前循环,还得继续下一轮的循环操作,并不会退出整个循环。