2.4 控制流

控制流是Python中非常重要的概念,也是任何一个编程语言的重要组成部分。有了控制流,我们才能编写出各种各样的程序。本节将介绍Python中的控制流,具体而言,就是Python中的判断语句与循环语句。

2.4.1 比较运算符

不同变量之间可以进行比较,而实现比较的具体方式就是使用比较运算符,比较运算符会返回布尔类型的结果。

Python中有多个比较运算符,具体如表2.1所示。

表2.1 比较运算符

img

使用部分比较运算符的示例代码如下:

img

变量a与变量b的比较很直观,数字10当然比数字17小。变量c与变量d中存放的是字符串,字符串之间也可以比较。字符串在比较时会依次获取字符串中的字符,然后通过内置的ord方法获取每个字符的Unicode编码并进行比较,如果相等则继续比较后续字符,直到字符不相等或整个字符串比较完才返回比较结果。观察如下代码:

img

可以发现,字符a对应的Unicode编码比字符b小,所以字符串abc小于字符串bbc,返回True。

字符串型的变量无法直接与整型变量比较,需要进行类型转换,不同的类型转换形式会导致不同的结果。示例代码如下:

img

在上述代码中,变量a是字符串型,而变量b是整型,因为两个变量类型不同,所以它们无法直接比较,会报TypeError错误。

如果字符串由纯数字字符组成,如变量a,则可以使用int方法将变量从字符串型转换为整型。

在上述代码中,将变量a转换为整型并与变量b比较,返回的布尔值为False。此外,还可以使用str方法将其他类型的变量转换为字符串型,如变量b。此时比较变量a与变量b,返回的布尔值为True。这就有点奇怪了,难道97大于100?

要注意,此时变量a与变量b都是字符串型,在比较时要按照字符串比较规则进行比较,所以首先比较的两个字符是字符9与字符1。通过ord方法可知,字符9对应的Unicode编码为57,而字符1对应的Unicode编码为49,57比49大,所以字符串97大于字符串100。

如果字符串中有非数字字符,此时使用int方法进行类型转换会报ValueError错误。这时,只能使用str方法将其他类型的变量转为字符串型后再进行比较,代码如下:

img

img

计算机底层其实只支持二进制的加法运算,不过利用补码也可以让加法起到减法的效果。在有了加法与减法这两种基本运算操作后,其他运算都可以通过加法与减法实现,如乘法可以通过多次相加来实现。

比较运算也一样,在计算机底层,比较运算其实就是两个二进制数据进行减法操作,如果结果等于0,则表示两数相等,反之则不相等。

在一些情景下,我们可以借鉴“使用减法做比较”的方式,比如,比较两个精度较高的小数,只要求差距小于0.0001就认为相等,那么该任务就可以通过减法来实现。示例代码如下:

img

2.4.2 逻辑运算符

有时单个比较语句无法满足要求,此时就可以使用逻辑运算符。逻辑运算符可以有机地组合多个比较语句,从而构成一个大的比较语句。Python中的逻辑运算符如表2.2所示。

表2.2 逻辑运算符

img

与操作:x与y中任意一个为False,整条语句就为False;只有x与y同时为True,整条语句才为True。

或操作:x与y同时为False,整条语句才为False;只要x与y中任意一个为True,整条语句就为True。

非操作:如果x为True,整条语句为False;如果x为False,整条语句为True。

示例代码如下:

img

将a> b表达式看作x,因为a为10,b为17,所以x应该为False;类似地,将c<d表达式看作y,y应该为True。

在上述代码中,因为x为False,所以使用and时,整条语句的结果为False;而使用or时,因为y为True并且是“或”的关系,所以整条语句的结果为True;最后的not相当于取反操作,x为False,取反后则为True。

2.4.3 判断语句

Python中通过if关键字构成判断语句,它通常由一条或多条语句的执行结果(True或False)来决定要执行的代码块。if直译为如果,if判断是指如果某个条件成立,那么就要做什么,否则就不做什么。示例代码如下:

img

上述代码中,if关键字后接一条比较语句,比较的结果会返回布尔值,if判断会依据布尔值执行相应的代码块。如果布尔值为True,则直接执行if关键字下的代码块;如果为False,则执行else关键字后的代码块。

如果想对多个条件进行判断,可以使用elif关键字;如果想一次判断多个条件,可以使用逻辑运算符将多个条件连接起来使用。示例代码如下:

img

2.4.4 循环语句

循环语句可以多次执行相应的代码块,在Python中,可以使用while关键字与for关键字来实现循环。下面是使用while关键字获得1~100相加结果的代码。

img

上述代码的逻辑其实很简单,一开始创建变量i与sum,变量i用于表示1~100的数值,变量sum用来表示1~100数值相加的结果,要实现1~100的相加,就需要重复进行50次累加操作,此时就需要使用while循环。

观察上述代码,while关键字后会接一个条件语句,如果该语句返回True,则会继续执行循环体中的代码;否则跳过循环体,执行循环体外的代码。具体到上述代码,如果i不大于100,就会执行while循环中的代码块;否则就跳出循环,执行循环外面的print方法,然后结束运行。

为了避免进入无限循环,要注意循环体中条件变量的变化。在上述代码中,条件变量就是变量i,如果变量i在循环体中没有变化,变量i就永远小于100,此时while关键字后的条件语句就永远为True,此时的while循环就成为无限循环,程序会一直运行循环体中的代码,不会结束,如以下代码所示:

img

无限循环其实非常常见,计算机里的很多程序都是无限循环的,最典型的是操作系统。例如,Windows操作系统本身就是一个复杂的程序,该程序在物理设备断电前一直处于循环中,不停地处理着用户或其他软件的指令。

在Python中,除了通过while关键字实现循环,还可以通过for关键字实现循环,语法为for…in…。示例代码如下:

img

上述代码在一开始时通过range方法获得1~100的可迭代对象,range方法接收两个参数,然后返回一个范围。该方法返回的范围会包含第一个参数,但不包含第二个参数,即返回一个左闭右开的区间。

接着我们使用for…in…语法操作可迭代对象,具体而言,就是从可迭代对象中迅速取出相应的值赋给变量i,然后执行for循环中的代码块。随着循环的进行,变量i的值会从1变成100,直到迭代完全部可迭代对象。

读者在简单理解while关键字与for关键字后,可以尝试思考如何通过while关键字或for关键字实现一个九九乘法表。

要实现九九乘法表,关键在于要意识到循环中还可以嵌套地实现循环。下面我们通过for关键字来实现九九乘法表,代码如下:

img

img

准确地说,for关键字其实实现的是迭代(iterate)操作,迭代与循环本身是有差异的,但都可以达到重复执行某代码块的效果。

● 循环指的是在满足条件的情况下,重复执行同一段代码,如Python中的while语句。

● 迭代指的是按照某种顺序逐个访问列表中的每一项,如Python中的for语句。

在Python中,可以使用for关键字操作的对象,通常都可以被称为可迭代对象。示例代码如下:

img

从上述代码可知,range方法返回的对象确实是可迭代对象,而变量a只是普通的数值对象,变量a并不能使用for…in…语法进行迭代操作。

2.4.5 跳出循环

通过while或for关键字构建循环操作可以很方便地让计算机处理重复操作,但在某些情况下我们并不希望让所有的操作都执行循环操作,此时就需要break或continue关键字来跳出循环。

break关键字会跳出整个循环,后续的循环逻辑不再执行。示例代码如下:

img

与break关键字不同,continue关键字只会跳出当次循环,后续循环依旧执行。示例代码如下:

img