第3章〓流程控制语句 案例导读 学习目标 理解程序的表示方法——程序流程图。 理解程序三大基本结构: 顺序结构、分支结构和循环结构。 掌握if、ifelse及ifelifelse语句的基本结构和语法。 掌握for、while循环的基本结构和语法。 掌握分支结构的嵌套、循环结构的嵌套,以及分支与循环的组合嵌套。 掌握break、continue及pass循环控制语句。 控制语句是程序语言的逻辑结构基础,也是程序编写的重点。掌握Python流程控制语句的应用,是进行程序和算法编写的必备条件。本章主要介绍Python的三大流程控制结构,顺序结构、分支结构和循环结构,使用这些流程控制语句可以控制程序的执行过程。其中,需要重点掌握if、ifelse、ifelifelse三种分支结构以及while、for两种循环结构。 3.1程序表示方法 3.1.1程序流程图 程序流程图是用代表各种不同操作的框图进行组合,演示算法流程的一种表现形式,更加直观形象,便于理解。表31是一些常用的程序流程图符号。 表31常用的程序流程图符号 符号描述符号描述 起止框处理框 输入输出框流程线 判断框连接点 流程图是表示算法的较好的工具。一个流程图包括以下几部分。 (1) 表示相应操作的框。 (2) 带箭头的流程线。 (3) 框内外必要的文字说明。 注意: 流程线不要忘记画箭头,它是用来反映流程先后逻辑的,若不画出箭头就难以判定各框的执行次序。用流程图表示算法直观形象,可以比较清楚地显示出各个框之间的逻辑关系。 3.1.2基本结构流程图 Python中主要有三种基本结构: 顺序结构、分支结构和循环结构。用这三种基本结构可以实现各种复杂算法的程序逻辑。 1. 顺序结构 图31顺序结构 流程图 顺序结构是最简单的一种基本结构,按照代码的顺序从上到下依次执行。顺序结构的流程图如图31所示。 2. 分支结构 Python分支结构也称为选择结构,就是让程序“拐弯”,有选择性地执行代码。换句话说,可以跳过没用的代码,只执行有用的代码。选择结构的流程图如图32所示,如果条件P成立,则执行A操作,否则执行B操作,然后程序继续往后执行。 3. 循环结构 Python循环结构又称为重复结构,就是不断地重复执行某一段代码。循环结构的流程图如图33所示。程序会首先判断条件P是否成立,如果成立则会执行A操作,然后再判断条件P,直到条件P不成立,循环结构终止,程序继续往后执行。 图32选择结构流程图 图33循环结构流程图 3.1.3流程图的应用 案例: 现需要判断数字序列1~100中,哪些数字为奇数,哪些数字为偶数,那么对应的程序思路如下。 (1) 运用循环结构循环生成1~100的数字。 (2) 再依次运用分支结构对数字奇、偶性进行判断。 (3) 按照判断结果进行输出,直到循环结束。 对应的程序流程图如图34所示。 图34程序流程图 3.2顺序结构 Python顺序结构是让程序按照从头到尾的顺序依次执行每一条 Python代码,不重复执行任何代码,也不跳过任何代码,代码如例31所示。 【例31】顺序结构的代码示例。 number1 = eval(input("请输入第一个数:")) number2 = eval(input("请输入第二个数:")) print(f"{number1}+{number2}={number1+number2}") 输出结果如下: 请输入第一个数:10 请输入第二个数:20 10+20=30 3.3分支结构 顺序结构的代码都是按顺序执行的,也就是先执行第1条语句,然后是第2条、第3条……直到最后一条语句。 但是很多情况下,顺序结构的代码是远远不够用的。实际开发场景中会有很多因为满足不同条件需要执行不同操作的需求。例如,网页界面的菜单栏中,需要选择不同选项来显示不同的网页内容,或满足不同条件时进行不同的数据处理等。接下来进行分支结构的介绍。 3.3.1单分支结构: if语句 if语句实现单分支处理,是最简单的条件判断语句。if语句的一般形式如下: if 表达式: 语句块1 如果表达式成立(真),那么执行后面的代码块1; 如果表达式不成立(假),那么什么也不执行,代码如例32所示。 【例32】单分支结构的代码示例。 score_cet4 = 424 if score_cet4 < 425: print("大学英语四级考试未通过,请继续努力。") print("单分支程序完成。") 输出结果如下: 大学英语四级考试未通过,请继续努力。 单分支程序完成。 由缩进可以看出,第一个print()输出语句属于此单分支结构,而第二个print()输出语句则不属于该结构。所以if单分支条件成立与否,只决定第一个print()函数是否输出数据; 第二个print()函数与if单分支结构无关。 注意: (1) 每个if条件后要使用冒号(:),是固定的语法规范,必须要写,表示判断条件的结束,开始分支语句的内容。 (2) 使用缩进来划分语句块,相同缩进数的语句在一起组成一个语句块。 3.3.2双分支结构: ifelse语句 if语句只能执行满足条件的程序代码,若不满足条件而需要执行其他程序代码,这时可以用ifelse语句来实现。ifelse语句的基本格式如下: if 表达式: 代码块1 else: 代码块2 如果表达式成立(真),则执行代码块1; 如果表达式不成立(假),则执行代码块2,代码如例33所示。 【例33】双分支结构的代码示例。 score_cet4 = 500 if score_cet4 < 425: print("大学英语四级考试未通过,请继续努力。") else: print("恭喜你成功通过大学英语四级考试。") print("双分支程序完成。") 输出结果如下: 恭喜你成功通过大学英语四级考试。 双分支程序完成。 双分支结构中执行else子句的隐含条件相当于是score_cet4>=425。注意: if和else的子句都需要缩进。 3.3.3多分支结构: ifelifelse语句 还有另一种情况,如果需要判断的条件数大于两种,而if和ifelse语句显然无法完成多条件判断,这时就需要用ifelifelse多条件判断语句。其基本格式如下: if 表达式1: 代码块1 elif表达式2: 代码块2 … elif 表达式n: 代码块n else: 代码块n+1 对于ifelifelse多条件判断语句,Python 会从上到下逐个判断表达式是否成立,一旦遇到成立的表达式,就执行后面紧跟的代码块; 此时,不管后面的表达式是否成立,剩下的代码都不再执行。如果所有的表达式都不成立,则执行 else 后面的代码块,代码如例34所示。 【例34】多分支结构的代码示例。 score_cet4 = int(input("请输入您的四级分数:")) if score_cet4 < 425: print("您的四级成绩未通过,请继续努力。") elif score_cet4 <=500: print("您的四级成绩合格。") elif score_cet4 <=600: print("您的四级成绩良好。") else: print("您的四级成绩优秀。") print("多分支程序完成。") 输出结果如下: 请输入您的四级分数:600 您的四级成绩良好。 多分支程序完成。 3.3.4嵌套分支结构: if嵌套语句 嵌套分支是指if、ifelse和ifelifelse语句还可以根据具体情况嵌入if、ifelse或ifelif语句。一般应用在有多维度条件的实际问题中,其基本格式如下: if 表达式1: 代码块1 if表达式2: 代码块2 else 表达式3: 代码块3 … elif 表达式n: 代码块n if 表达式n+1: 代码块n+1 else: 代码块n+2 … 对于嵌套分支的执行流程,遵循从外到内依次判断的顺序,而嵌套的不管是单分支、双分支还是多分支,其执行流程和其他分支结构的规则一致,代码如例35所示。 【例35】嵌套分支结构的代码示例。 ticket = True liquid_v = 150 if ticket: print('已有机票,请安检……') if liquid_v >100: print('液体体积为{}ml:超出限定容量,禁止登机'.format(liquid_v)) else: print('液体体积为{}ml:没有超过限定容量,允许入内'.format(liquid_v)) else: print('请先买票') 输出结果如下: 已有机票,请安检…… 液体体积为150ml:超出限定容量,禁止登机 3.4循环语句 在日常生活中或是在程序所处理的问题中常遇到需要重复处理的问题,处理这些重复问题的常用方法是编写若干个重复语句。虽然这种方法可以满足需求,但是代码冗余度高、工作量大、效率低。因此,想要高效地重复执行某些操作,可以使用循环语句。 3.4.1while语句 while语句和if语句类似,即在条件(表达式)为真的情况下,会执行相应的代码块。不同之处在于,只要条件为真,while 语句会一直重复执行相应的代码块。while 语句的语法格式如下: while 条件表达式: 代码块 这里的代码块指的是缩进格式相同的多行代码,在语句结构中,它又被称为循环体。while语句执行的具体流程为: 首先判断条件表达式的值,其值为真(True)时,则执行代码块中的语句,当执行完毕后,再重新判断条件表达式的值是否为真。若仍为真,则继续执行代码块,如此循环,直到条件表达式的值为假(False),则终止循环,代码如例36所示。 【例36】while语句的代码示例。 # 求解10的阶乘 result = 1 i = 1 while i <=10: result *= i i += 1 print(result) 以上代码求解10的阶乘结果为3628800,使用while语句,需要注意三点: 循环控制变量i的初始值、对应的循环条件和改变循环控制变量的语句,即i+=1。另外,存储最终乘积的result也需要赋予初始值,否则程序语句result*=i会报错。 Python中的while语句可以跟分支结构中的else关键字搭配使用。当while语句正常结束后,会执行else中的语句; 若是非正常终止的,即循环是通过break关键字直接终止的,则不会执行else中的语句。 例如,若要实现数字炸弹的游戏,则可以使用while语句和else的搭配来实现。其中游戏规则如下。 (1) 随机生成指定范围内的某一个数字,如1~1000中的随机整数。 (2) 然后循环地猜测随机数是哪个,直到猜中为止。 代码如例37所示。 【例37】while语句和else搭配使用的代码示例。 from random import randint number = randint(1, 1000) guess_number = int(input("请随机输入一个整数:")) while number != guess_number: if number < guess_number: print("您猜的数字大了!请再猜一次。") elif number >guess_number: print("您猜的数字小了!请再猜一次。") guess_number = int(input("请随机输入一个整数:")) else: print("恭喜您!猜对了!") 输出结果如下: 请随机输入一个整数:500 您猜的数字小了!请再猜一次。 请随机输入一个整数:750 您猜的数字大了!请再猜一次。 请随机输入一个整数:600 您猜的数字小了!请再猜一次。 请随机输入一个整数:650 您猜的数字大了!请再猜一次。 请随机输入一个整数:625 您猜的数字大了!请再猜一次。 请随机输入一个整数:620 您猜的数字小了!请再猜一次。 请随机输入一个整数:621 恭喜您!猜对了! while语句循环的条件是number!=guess_number,循环正常终止的对应条件正好是number与guess_number相等,也正好执行else内的语句,输出结果“恭喜您!猜对了!”。 3.4.2for语句 3.4.1节已详细讲解了while语句,本节介绍for语句,它常用于遍历字符串、列表、元组、字典、集合等可迭代对象,逐个获取这些对象中的各个元素。for语句的语法格式如下: for 循环变量 in 可迭代对象: 代码块 循环变量用于存放从可迭代对象中读取的元素,所以一般不会在循环结构中对循环变量手动赋值; 循环的对象一般为字符串、列表、元组、字典、集合等数据; 代码块指的是具有相同缩进格式的多行代码(和 while语句一样),由于与循环结构联用,因此代码块又被称为循环体。 for语句可以遍历字符串、列表、字典和集合等可迭代对象,代码如例38所示。 【例38】for语句的代码示例。 # 1. for语句循环遍历字符串 str1 = "武汉是一座英雄的城市" for character in str1: print(character, end="") # 2. for语句循环遍历列表 circle_color = ["blue", "black", "red", "yellow" ,"green"] for color in circle_color: print(color, end=" ") # 3. for语句循环遍历字典 stu_dict = {"院系": "计信学院", "学号": "12345678", "姓名": "小哈"} for key in stu_dict: print(key, stu_dict[key]) # 4. for语句循环遍历集合 Set = {(3, 4), True, "abc", 12.3} for i in Set: print(i, end=" ") 输出结果如下: # 1. for语句循环遍历字符串 武汉是一座英雄的城市 # 2. for语句循环遍历列表 blue black red yellow green # 3. for语句循环遍历字典 院系 计信学院 学号 12345678 姓名 小哈 # 4. for语句循环遍历集合 abc True (3, 4) 12.3 3.4.3嵌套循环 不仅if语句支持相互嵌套,while和for循环结构也支持嵌套。例如,for循环里面包含for循环、while循环里面包含while循环,甚至while循环中包含for循环或for循环中包含while循环也都是允许的。 当两个(甚至多个)循环结构相互嵌套时,位于外层的循环结构常简称为外层循环或外循环,位于内层的循环结构常简称为内层循环或内循环,代码如例39所示。 【例39】使用嵌套for循环求1!+2!+3!+…+n!的代码示例。 n = int(input("请输入计算阶乘的个数:")) sum1 = 0 for i in range(1, n+1): mul = 1 for j in range(1, i+1): mul *= j sum1 += mul print("1!+…+{}!={}".format(n, sum1)) 输出结果如下: 请输入计算阶乘的个数:5 1!+…+5!=153 外层循环变量i等于1,内层循环计算1的阶乘,然后加上sum1; 接着外层循环i变成2,内层循环再计算2的阶乘,再加上sum1,后面依次计算3!、4!和5!,并且求和,存入sum1中,最后得出阶乘总和为153。 用while循环来求解1!+2!+3!+…+n!,代码如例310所示。 【例310】使用嵌套while循环求1!+2!+3!+…+n!的代码示例。 n = int(input("请输入计算阶乘的个数:")) sum1, i = 0, 1 # 循环变量i的初值 while i < n+1: # 外层循环的条件 mul = j = 1 # 循环变量j的初值 while j < i+1: # 内层循环的条件 mul *= j j += 1 # 改变内层循环变量j的语句 sum1 += mul i += 1 # 改变外层循环变量i的语句 print("1!+…+{}!={}".format(n, sum1)) 输出结果如下: 请输入计算阶乘的个数:6 1!+…+6!=873 由例39和例310可以看出,一般情况下,当循环次数固定时,for循环的写法比while循环更简单; 而当循环次数不固定,且跟循环体的执行情况相关时,一般可以优先选择使用while循环。 Python解释器执行循环嵌套结构代码的流程如下。 (1) 当外层循环条件成立时,执行外层循环结构中的循环体。 (2) 进入外层循环的循环体后,执行内层循环,直到内层循环结束。 (3) 内层循环结束后,再次判断外层循环条件,若仍成立,则返回第(2)步,反复执行,直到外层循环的循环条件不成立为止,整个循环结束。 (4) 当内层循环的循环条件不成立,且外层循环的循环条件也不成立时,则整个嵌套循环才算执行完毕。 在计算机领域中,认为编写的程序=数据结构+算法,数据结构的好坏直接关系到程序的质量,而在实际开发过程中经常会用到的各类排序算法的思想,如冒泡排序、选择排序和快速排序等,不同的排序方法处理数据的效率各有不同。现在以冒泡排序的代码为例,阐述嵌套循环的代码特点及流程。 冒泡排序(Bubble Sort)是一种简单、直观的排序算法。它重复地访问要排序的数列,一次比较两个元素。以升序为例,如果比较的两个元素前一个大于后一个,就对它们的位置进行交换,然后重复地进行,直到没有再需要交换的元素,那么该数列已经排序完成。 冒泡排序的思想如下。 第一,比较相邻的元素。如果第一个比第二个大,就对它们进行交换。 第二,对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。 第三,针对所有的元素重复以上的步骤,除了最后一个。 第四,持续对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。 演示代码如例311所示。 【例311】嵌套循环——冒泡排序代码示例。 sort_num = [34, 12, 67, 13, 2, 100, 79, 23, 35, 89] length = len(sort_num) for i in range(length -1): for j in range(length -i-1): if sort_num[j] >sort_num[j+1]: sort_num[j], sort_num[j+1] = sort_num[j+1], sort_num[j] print(sort_num) 输出结果如下: [2, 12, 13, 23, 34, 35, 67, 79, 89, 100] 由冒泡排序的思想可以推出,n个数字只需要比较n-1轮,也就是例311中第一个for循环的length-1; 而每一轮内部的比较次数依次是n-1次、n-2次、n-3次、……、2次、1次,也就是第二个for循环中的length-i-1。然后,Python中交换两个变量中的数据可以直接写成a,b=b,a的形式,所以交换sort_num[j]和sort_num[j+1],就可以直接写成sort_num[j],sort_num[j+1]=sort_num[j+1],sort_num[j]。 3.4.4循环控制语句: break、continue和pass语句 在执行while循环或for循环时,只要循环条件满足,程序将会一直执行循环体,不停地循环。但某些场景需要在循环结束前就强制结束循环,Python 提供了两种强制离开当前循环体的方法: break语句和continue语句。此外,Python 还提供了pass语句,用来让解释器跳过此处,什么都不做。 1. break语句 break语句可以立即终止当前循环的执行,跳出当前所在的循环结构。无论是while循环还是for循环,只要执行break语句,就会直接结束当前正在执行的循环体。 这就好比在操场上跑步,原计划跑5圈,可是当跑到第 3圈的时候,临时有事,于是直接停止跑步并离开操场,这就相当于使用了break语句提前终止了循环。 break 语句的语法非常简单,只需要在相应 while 或 for 循环中直接加入即可,代码如例312所示。 【例312】使用break语句的代码示例。 for i in range(1, 6): if i == 3: print("第3圈临时有事,停止锻炼。") break print("这是第{}圈"。format(i)) 输出结果如下: 这是第1圈 这是第2圈 第3圈临时有事,停止锻炼。 例37中实现数字炸弹游戏,是使用while循环和else搭配实现的,那么使用while循环和break搭配也同样能实现,代码如例313所示。 【例313】while循环和break搭配使用的代码示例。 from random import randint number = randint(1,1000) while True: guess_number = int(input("请随机输入一个整数:")) if number < guess_number: print("您猜的数字大了!请再猜一次。") elif number >guess_number: print("您猜的数字小了!请再猜一次。") else: print("恭喜您!猜对了!") break 输出结果如下: 请随机输入一个整数:500 您猜的数字大了!请再猜一次。 请随机输入一个整数:250 您猜的数字小了!请再猜一次。 请随机输入一个整数:375 您猜的数字小了!请再猜一次。 请随机输入一个整数:435 您猜的数字大了!请再猜一次。 请随机输入一个整数:405 您猜的数字小了!请再猜一次。 请随机输入一个整数:420 您猜的数字大了!请再猜一次。 请随机输入一个整数:415 您猜的数字大了!请再猜一次。 请随机输入一个整数:410 恭喜您!猜对了! 将while循环的条件设置为True,是while循环中的一种特殊写法,True代表循环条件永远成立,也就意味着循环无法通过条件终止,但可以通过break来进行终止,例313中,不论玩家猜的数字是大还是小,都无法终止循环,只有当猜对之后,需要终止,所以在else分支内部加一个break即可。 2. continue语句 和break语句相比,continue语句的作用则没有那么强大,它只能终止执行本次循环中剩下的代码,直接从下一次循环继续执行。 仍然以在操场上跑步为例,原计划跑 5圈,但跑到第3圈累了,第3圈不跑,改为走一圈,休息一会儿,并直接从第4圈开始跑。 continue语句的用法和break语句一样,只要在while或 for循环中的相应位置加入即可,代码如例314所示。 【例314】continue语句的使用代码示例。 for i in range(1, 6): if i == 3: print("第3圈走一圈,休息一会儿。") continue print("第{}圈跑步运动".format(i)) 输出结果如下: 第1圈跑步运动 第2圈跑步运动 第3圈走一圈,休息一会儿。 第4圈跑步运动 第5圈跑步运动 3. pass语句 在实际开发中,有时会先搭建起程序的整体逻辑结构,暂时不去实现某些细节,而是在这些地方加一些注释,方便以后再添加代码,同样可以用pass语句作为占位符,实现同样的功能,且程序代码看起来更简洁、美观,代码如例315所示。 【例315】使用pass语句的代码示例。 for i in range(1, 6): if i == 3: pass print("第{}圈跑步运动".format(i)) 输出结果如下: 第1圈跑步运动 第2圈跑步运动 第3圈跑步运动 第4圈跑步运动 第5圈跑步运动 该代码示例中,当i等于3时,满足分支条件,但是里面处理的代码,还没有确定怎么写,那么可以先用pass语句进行占位,此时相当于满足条件,但什么都不做。这样就可以先运行其他代码,保持程序结构完整性,不会因为缺少语句导致程序出错。如果确定了分支结构中的程序语句怎么写了,直接删除pass语句,补充对应程序语句即可。 pass也是Python 的关键字之一,用来让解释器跳过此处,什么都不做。就像上面的情况,有时候程序需要占一个位置或放一条语句,但又不希望这条语句被执行,此时就可以通过 pass 语句来实现。使用 pass 语句比使用注释更加美观。 视频讲解 3.5实训案例 小红和小芳商量下周如何度过,如果是周末,温度高于30℃,就去游泳,否则就去爬山;非周末,假如天气好,就去旅游,否则,就去图书馆学习。编写程序,实现上述推荐选择。 1. 案例的实现思路 (1) 建议定义三个变量,分别存放周几、温度和天气。 (2) 利用if语句来实现。 2. 案例参考代码 print('请输入周几\n') day = input() #今天周六 print('请输入温度\n') temp = input() #温度为31℃ print('请输入天气\n') weather = input() if day == 6 or day == 7: if temp >30: print("建议您去游泳") else: print("建议您去爬山") else: if weather == "天气好": print("建议您去旅游") else: print("建议您去图书馆学习") 运行结果如图35所示。 图35运行结果 本章小结 本章主要介绍Python的流程控制结构,包括顺序结构、分支结构、循环结构,使用流程控制语句可以控制程序的执行过程。其中,需要重点掌握if、ifelse、ifelifelse分支结构、while、for循环结构、选择及循环的嵌套用法。 习题 一、 判断题 1. 对于带有else子句的循环语句,如果是因为循环条件表达式不成立而自然结束循环,则执行else子句中的代码。() 2. while循环的循环体至少执行一次。() 3. 在循环语句中,continue语句的作用是跳过当前循环中的剩余语句,提前进入下一次循环。() 4. 在循环语句中,break语句的作用是提前结束本层循环。() 5. Python提供了两种实现循环的语句,分别是while和for。() 二、 选择题 1. 执行以下代码,其结果为()。 n = 20 sum = 0 number = 1 while number <=n: sum = sum + number number += 1 print(sum) A. 0B. 209C. 210D. 66 2. 阅读下面的代码: sum = 0 for i in range(10): if(i%5): continue sum = sum + i print(sum) 上述程序的执行结果是()。 A. 5B. 4C. 3D. 10 3. 已知x=5,y=6,z=7,以下语句执行后x、y、z的值是()。 if x=90分输出A,60~89分输出B,60分以下输出C。