代替VBA!用Python轻松实现Excel编程
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.11 流程控制

变量是计算机语言中最基本的语言元素,表达式用运算符连接变量构成一个更长的代码片段或者说一条语句,此时我们已经具备写一行语句的能力。在学完流程控制以后,我们将具备写一个代码块,即多行语句的能力。多行语句通过流程控制语句连接变量和表达式,形成一个完整的逻辑结构,是一个局部的整体。常见的流程控制结构有判断结构、循环结构等。

1.11.1 判断结构

判断结构测试一个条件表达式,然后根据测试结果执行不同的操作。Python支持多种不同形式的判断结构。判断结构用if语句进行逻辑判断。

1. 单行判断结构

单行判断结构具有下面的形式:

其中,判断条件常常是一个关系运算表达式或逻辑运算表达式,当条件满足时执行冒号后面的语句。

在下面的两行代码中,第1行用input函数实现一个输入提示,提示输入一个数字;第2行实现一个单行判断结构,判断输入的数字是否等于1,如果是,则输出字符串"输入的值是1"。该文件位于Samples目录下的ch01子目录中,文件名为sam01-01.py。

在Python IDLE文件脚本窗口中,在“Run”菜单中单击“Run Module”选项,则IDLE命令行窗口提示“请输入一个数字:”,输入1,按回车键,显示下面的结果:

2. 二分支判断结构

二分支判断结构具有下面的形式:

当判断条件满足时执行第1个冒号后面的语句,当不满足时执行第2个冒号后面的语句。

下面的代码实现了一个二分支判断结构。该文件位于Samples目录下的ch01子目录中,文件名为sam01-02.py。

第1行用input函数实现一个输入提示,提示输入一个数字;第2~5行为二分支判断结构,判断输入的数字是否大于0,如果是,则输出字符串"成功。",否则输出字符串"失败。"。

在Python IDLE文件脚本窗口中,在“Run”菜单中单击“Run Module”选项,则IDLE命令行窗口提示“请输入一个数字:”,输入5,按回车键,显示下面的结果:

3. 多分支判断结构

多分支判断结构具有下面的形式:

多分支判断结构提供多重条件判断,当第1个条件不满足时测试第2个条件,当第2个条件不满足时测试第3个条件,依此类推。当当前条件满足时执行相应的语句,最后都不满足时执行相应的语句。

下面的代码用一个多分支判断结构判断给定的成绩属于哪个等级。该文件位于Samples目录下的ch01子目录中,文件名为sam01-03.py。

第1行用input函数实现一个输入提示,提示输入一个数字;第2~11行为多分支判断结构,判断输入的成绩属于哪个等级。

在Python IDLE文件脚本窗口中,在“Run”菜单中单击“Run Module”选项,则IDLE命令行窗口提示“请输入一个数字:”,输入88,按回车键,显示下面的结果:

4. 有嵌套的判断结构

有嵌套的判断结构具有类似于下面的形式,如果分支条件满足,则进行次一级的条件判断和处理。

现在将前面对成绩分等级的示例进行改写,如下面的代码所示。该文件位于Samples目录下的ch01子目录中,文件名为sam01-04.py。

第1行用input函数实现一个输入提示,提示输入一个数字;第2~12行为有两层嵌套的判断结构,判断输入的成绩属于哪个等级。外面第1层嵌套判断给出的成绩是否大于或等于60分,如果条件满足,则用一个多分支判断结构细分及格及以上的成绩等级,这是第2层判断结构。最后都不满足时表示成绩不及格。

在Python IDLE文件脚本窗口中,在“Run”菜单中单击“Run Module”选项,则IDLE命令行窗口提示“请输入一个数字:”,输入88,按回车键,显示下面的结果:

下面再举一个判断闰年的例子。该文件位于Samples目录下的ch01子目录中,文件名为sam01-05.py。闰年包括世纪闰年和普通闰年。世纪闰年可以被400整除,普通闰年能被4整除,不能被100整除。

第1行指定用来判断的年份2020;第2~10行为有两层嵌套的判断结构,判断指定年份是不是闰年。首先判断年份是不是世纪闰年,即能不能被400整除;如果不能,则进一步判断是不是普通闰年。判断普通闰年用到两层嵌套,先判断年份是否能被4整除,如果能,则进一步判断是否不能被100整除。最后判断的结果保存在布尔型变量yn中。第11~14行输出结果,如果yn的值为True,则输出年份是闰年;否则输出年份不是闰年。

在Python IDLE文件脚本窗口中,在“Run”菜单中单击“Run Module”选项,则IDLE命令行窗口显示下面的结果:

5. 三元操作符

简单的二分支判断结构可以用类似于下面的三元操作表达式代替。

如果判断条件满足,则结果为b,否则结果为a。

下面用三元操作表达式判断给定的数是否大于或等于10。该文件位于Samples目录下的ch01子目录中,文件名为sam01-06.py。

第1行用input函数实现一个输入提示,提示输入一个数字;第2行用三元操作表达式判断输入的数是否大于或等于10,如果是,则输出字符串">=10",否则输出字符串"<10"。

在Python IDLE文件脚本窗口中,在“Run”菜单中单击“Run Module”选项,则IDLE命令行窗口提示“请输入一个数字:”,输入15,按回车键,显示下面的结果:

下面用三元操作表达式求给定的三个数中的最小值。该文件位于Samples目录下的ch01子目录中,文件名为sam01-07.py。

第1行给定三个数10、30和20,分别赋给变量x、y和z;第2行用三元操作表达式比较x和y的大小,将二者的较小值赋给变量small;第3行用三元操作表达式比较small和z的大小,将二者的较小值赋给变量small;第4行输出small的值。

在Python IDLE文件脚本窗口中,在“Run”菜单中单击“Run Module”选项,则IDLE命令行窗口显示下面的结果:

1.11.2 循环结构——for循环

循环结构允许重复执行一行或数行代码。

1. for循环

使用for循环可以遍历指定的可迭代对象,即针对可迭代对象中的每个元素执行相同的操作。for循环的语法结构为:

可迭代对象包括字符串、区间、列表、元组、字典、迭代器对象等。

下面对字符串应用for循环,逐个输出字符串中的每个字符。

输出结果为:

下面对区间应用for循环,逐个输出区间中的每个数字。

输出结果为:

下面对列表应用for循环,逐个输出列表中每个城市的名称。

输出结果为:

对于列表,也可以使用区间,结合列表索引来输出列表中的元素。下面通过索引输出列表中各城市的名称。

输出结果为:

下面对元组应用for循环,逐个输出元组中每个元素的数据。

输出结果为:

下面对字典应用for循环,逐个输出字典中各项的键、值和键值对。

输出结果为:

输出结果为:

输出结果为:

输出结果为:

下面使用for循环对1~10的整数进行累加。该文件位于Samples目录下的ch01子目录中,文件名为sam01-08.py。

第1行给sum赋初值0,该变量记录累加和;第2行给num赋初值,该变量为for循环的迭代变量,逐个取区间1~10中的数;第3行和第4行使用一个for循环对1~10各数进行累加;第5行输出累加和。

在Python IDLE文件脚本窗口中,在“Run”菜单中单击“Run Module”选项,则IDLE命令行窗口显示下面的结果。

2. for…else用法

for循环还提供了一种for…else用法,else中的语句在循环正常执行完成时执行。下面判断一个整数是不是质数。判断一个整数是否是质数的算法是,用2到这个整数的区间内的每个数作为除数去除该整数,如果该整数能被至少一个数整除,那么它就不是质数,否则是质数。该文件位于Samples目录下的ch01子目录中,文件名为sam01-09.py。

第1行使用input函数输入一个整数;第2~7行使用一个for…else结构判断给定的整数是不是质数。只要出现n能被2至n中的某个数整除的情况就中断循环,输出它不是质数;如果遍历完后没有出现这种情况,则输出它是质数。

在Python IDLE文件脚本窗口中,在“Run”菜单中单击“Run Module”选项,则IDLE命令行窗口提示“请输入一个数字:”,输入5,按回车键,显示下面的结果:

再次运行,输入9,按回车键,显示下面的结果:

3. for循环嵌套

下面用两层嵌套的for循环生成九九乘法表。该文件位于Samples目录下的ch01子目录中,文件名为sam01-10.py。

第1行用for循环的迭代变量i在1~9中逐个取值,给出各乘式的第1个因子;第2行对变量s初始化为空字符串,该变量记录一行乘式;第3行用内层for循环的迭代变量在1~i之间逐个取值,作为各乘式的第2个因子,因为在1~i之间取值,最后得到的乘法表是一个下三角的形状;第4行用字符串对象的format函数格式化组装乘式,各乘式之间用制表符间隔;第5行输出当前行的所有乘式。最后,九九乘法表的所有乘式就是这样一行一行生成的。

在Python IDLE文件脚本窗口中,在“Run”菜单中单击“Run Module”选项,则IDLE命令行窗口显示下面的结果:

1.11.3 循环结构——while循环

for循环遍历指定的可迭代对象,该对象的长度即对象中元素的个数是确定的,所以循环次数是确定的。还有一种情况,就是一直循环,直到满足指定的条件为止,此时循环次数是不确定的,事先未知。这种循环用while循环来实现。while循环可有多种形式。

1. 简单的while循环

单行while循环的形式为:

其中,判断条件为一个关系运算表达式或逻辑运算表达式,当满足条件时执行冒号后面的语句。

下面用简单的while循环求1~10的累加和。该文件位于Samples目录下的ch01子目录中,文件名为sam01-11.py。

第1行给sum赋初值0,该变量记录累加和;第2行给num赋初值,该变量为while循环的迭代变量,逐个取区间1~10中的数;第3~5行用一个while循环对1~10各数进行累加;第4行进行累加计算;第5行对迭代变量的值加1,取下一个值;第6行输出累加和。

在Python IDLE文件脚本窗口中,在“Run”菜单中单击“Run Module”选项,则IDLE命令行窗口显示下面的结果:

2. 有分支的while循环

有分支的while循环结构中有else关键字,形式为:

当判断条件满足时,执行第1个冒号后面的语句;当不满足时执行第2个冒号后面的语句。

下面改写对1~10累加求和的例子。当迭代变量的取值大于10时给出提示。当然,在实际编程时没必要这么做,这里是为了演示循环结构。该文件位于Samples目录下的ch01子目录中,文件名为sam01-12.py。

第1~5行实现累加求和;第6行和第7行在n的值大于10时给出提示;第8行输出累加和。

在Python IDLE文件脚本窗口中,在“Run”菜单中单击“Run Module”选项,则IDLE命令行窗口显示下面的结果:

3. while循环嵌套

下面用嵌套的while循环生成九九乘法表。该文件位于Samples目录下的ch01子目录中,文件名为sam01-13.py。

第1行给变量i赋初值0,变量i是外层循环的迭代变量;第2~8行生成九九乘法表,在外层循环中,迭代变量i的值每迭代一次加1,直到等于9,每次迭代都用内层循环生成乘法表中的一行;第6~8行为内层循环,判断条件为迭代变量j的值小于i,对j累加,生成当前行的乘式;第9行输出乘法表。

在Python IDLE文件脚本窗口中,在“Run”菜单中单击“Run Module”选项,则IDLE命令行窗口显示下面的结果:

while循环还可以和for循环嵌套,下面将内层while循环改写成for循环生成九九乘法表。该文件位于Samples目录下的ch01子目录中,文件名为sam01-14.py。

请大家自行解读代码,这里不再赘述。

4. 避免死循环

前面讲过,for循环的循环次数是确定的,它的循环次数就是所用可迭代对象的长度。while循环的循环次数则不确定,如果判断条件一直满足,则可以一直循环下去,即进入“死循环”的状态。此时,可以使用break语句跳出循环。在命令行窗口中出现这种情况,可以按“Ctrl+C”键终止循环。

1.11.4 其他结构

本节介绍其他几个命令语句,包括break、continue和pass语句等。

1. break语句

break语句用在while循环或for循环中,在必要时用于终止和跳出循环。

下面用for循环对给定的数据区间进行累加求和,要求累加和的大小不能超过100;否则,使用break语句终止和跳出循环。该文件位于Samples目录下的ch01子目录中,文件名为sam01-15.py。

第6行加了一个单行判断结构,当累加和大于100时使用break语句跳出循环。第7行和第8行分别输出最后小于100的累加和及其对应的数字。

在Python IDLE文件脚本窗口中,在“Run”菜单中单击“Run Module”选项,则IDLE命令行窗口显示下面的结果:

也可以在while循环中使用break语句跳出循环。使用while循环改写上面的程序。该文件位于Samples目录下的ch01子目录中,文件名为sam01-16.py。

运行该程序,输出相同的计算结果。

2. continue语句

continue语句与break语句的作用类似,都是用在循环中,用于跳出循环。不同的是,break语句是跳出整个循环,continue语句则是跳出本轮循环。

下面的for循环输出0~4区间内的整数,但是不输出3。该文件位于Samples目录下的ch01子目录中,文件名为sam01-17.py。

第2行用了一个单行判断结构,当迭代变量取值为3时使用continue语句跳出本轮循环。

在Python IDLE文件脚本窗口中,在“Run”菜单中单击“Run Module”选项,则IDLE命令行窗口显示下面的结果:

可见,整数3没有输出。

3. pass语句

pass语句是占位语句,它不做任何事情,只用于保持程序结构的完整性。在判断结构中,当判断条件满足时,如果什么也不执行,则会出错。例如,在文件或命令行中执行下面的语句会出错:

此时将pass语句放在冒号后面,虽然还是什么也不做,但保证了语法上的完整性,就不会出错了。即:

另外,在自定义函数时,如果定义一个空函数,也会出错。此时在函数体中放一个pass语句,就不会出错了。