
3.3 循环结构
循环问题体现在日常生活的方方面面,例如,学生上学,每天从宿舍到教室,往返于这两个点。类似这样反复做同一件事的情况,称为循环。
循环主要有两种类型:重复一定次数的循环,称为计次循环。如for循环。一直重复,直到条件不满足时才结束的循环,称为条件循环。只要条件为真,这种循环会一直持续下去。如while循环。
3.3.1 while语句
while循环是通过一个条件来控制是否要继续反复执行循环体中的语句。while语句用于在满足循环条件时重复执行某件事情,其流程如图3-6所示。

图3-6 while循环结构流程图
从图中可以看出,当表达式的值为真时,执行相应的语句块(循环体),然后再判断表达式的值,如果为真,则继续执行语句块;当表达式的值为假时,检查其后面是否有else子句(因为可选,所以流程图未画出),如果有,则执行else子句;如果没有,则直接跳出while语句,执行其下面的语句。
语法格式:

循环体是指一组被重复执行的语句。
【例3-12】 将“不忘初心”输出3次。

运行结果:

在使用while语句时,需要注意以下事项。
1)与if语句类似,while语句的表达式可以是任意类型,如x!=y,x﹥3 or x﹤5,-5等。
2)循环体中的语句块有可能一次也不执行,上例中若初始值i=4,则语句块不会执行。
3)语句块可以是一条或多条语句,上例中while子句中的语句块为两条语句,else子句中的语句块为一条语句。
4)程序中需要包含使循环结束的语句,上例中若缺少语句i=i+1,则程序无法终止。
死循环:在while循环中,如果表达式的值恒真,循环将一直执行下去,无法靠自身终止,从而产生死循环。
例如:

书写程序时,有时要尽量避免死循环,但是在某些特定场合中死循环却具有十分重要的作用,如嵌入式编程、网络编程中等。
【例3-13】 编写程序,用下列公式计算π的近似值,直到最后一项的绝对值小于10-6为止。

分析:观察π的计算公式可知,循环变量的初始值为1,循环条件为循环变量的绝对值大于等于10-6,循环变量值的变化规律如上式所示,每项的分母比上一项增加2,符号与上一项相反。

运行结果:

【例3-14】 取款机输入密码模拟。一般在取款机上取款时需要输入6位银行卡密码,接下来模拟一个简单的取款机(只有1位密码),每次要求用户输入1位数字密码,密码正确输出“密码输入正确,正进入系统!”:如果输入错误,输出“密码输入错误,您已经输入*次”,密码连续输入错误6次后输出“您的卡将被锁死,请和发卡行联系”。
分析:每次输入1个字符,默认密码为0,连续输入6次错误后提醒,并退出。

运行结果:

3.3.2 for语句和range内建函数
for循环语句是一个计次循环,通常适用于枚举或遍历序列,以及迭代对象中的元素。一般应用在循环次数已知的情况下。
基本语法如下。

其中,迭代变量用于保存读取出的值;对象为要遍历或迭代的对象,该对象可以是任何有序的序列对象,如字符串、列表和元组等;循环体为一组被重复执行的语句。
1.进行数值循环
在使用for循环时,最基本的应用就是进行数值循环。循环可以帮助我们解决很多重复的输入或计算问题。可以利用数值循环输出3遍“不忘初心”,代码如下。

【例3-15】 利用数值循环输出列表的值,如输出[”pku”,”tsinghua”,”fudan”,”sjtu”,”nju”,”zju”,”ustc”]中的值。

运行结果:

利用列表可以输出一些简单重复的内容,但如果循环次数过多,如要实现从1到100的累加,可以使用range函数。
range函数是Python内置的函数,用于生成一系列连续的整数。多用于for循环语句中。其语法格式为:range(start,end,step)。
参数说明:
1)start:用于指定计数的起始值,可以省略,如果省略,默认值为0。
2)end:用于指定计数的结束值(但不包括该值,如range(7)得到的值为0-6,不包括7),不能省略。当range函数中只有一个参数时,即表示指定计数的结束值。
3)step:用于指定步长,即两个数之间的间隔可以省略,如果省略则表示步长为1。例如,rang(1,7)将得到1、2、3、4、5、6。
● 若指定step为0,则抛出ValueError异常。
● 当step为正时,range的值由公式:r[i]=start+step×i,而i≥0并且r[i]﹤stop。
● 当step为负时,range的值由公式:r[i]=start+step×i,而i≥0并且r[i]﹥stop。
在使用range函数时,如果只有一个参数,那么表示指定的是end;如果是两个参数,则表示指定的是start和end;只有三个参数都存在时,最后一个才表示步长。
【例3-16】 计算1+2+3+4+...+100的结果。

运行结果:

2.遍历字符串
使用for循环语句除了可以循环数值,还可以逐个遍历字符串。
【例3-17】 以遍历方式计算出“黑化肥发灰会挥发;灰化肥挥发会发黑”中“发”在字符串中出现的次数。

运行结果:

【例3-18】 编写程序,解决以下问题。
4个人中有一人做了好事,已知有三个人说了真话,根据下面对话判断是谁做的好事。
A说:不是我;
B说:是C;
C说:是D;
D说:C胡说。
分析:做好事的人是4个人其中之一,因此可以将4个人的编号存入列表中,然后使用for循环依次判断;有三个人说了真话,将编号依次代入,使用if语句判断是否满足“三人说真话”(三个逻辑表达式的值为真)的条件,如果满足,则输出结果。
for iNum in ['A','B','C','D']:if(iNum!='A')+(iNum=='C')+(iNum=='D')+(iNum!='D')==3:print(iNum,”做了好事!”)
运行结果:

3.迭代对象
从理论上来说,循环对象和for循环调用之间还有一个中间层,该层将循环对象转换可迭代对象。这一转换通过使用iter函数实现。但从逻辑层面上,常常可以忽略这一层,所以循环对象和可迭代对象常常相互指代对方。
后续章节所要讲述的列表、元组、字符串、集合等都是可迭代对象,所谓可迭代对象是指的是可以返回一个迭代器的对象,如果不清楚哪个是可迭代对象,可以通过Python内建的iter函数测试。比如print(iter(range(1,100,1))),运行后显示:﹤range_iterator object at 0x000000000209F750﹥,即iter函数为range返回了range_iterator对象。
3.3.3 循环语句嵌套
在Python中,允许在一个循环体中嵌入另一个循环,这称为循环嵌套。for循环和while循环都可以进行循环嵌套。
为了解决复杂的问题,可以使用循环语句的嵌套,嵌套层数不限,但是循环的内外层之间不能交叉。其中,双层循环是一种常用的循环嵌套,循环的总次数等于内外层次数之积。例如:


当外层循环变量i的值为1时,内层循环j的值从1开始,输出i*j的值并依次递增,因此输出“1 2 3”,内层循环执行结束;然后回到外层循环,i的值递增为2,内层循环变量i的值重新从1开始,输出i*j的值,并依次递增,输出“2 4 6”。因此,程序的运行结果为“123246”。
【例3-19】 编写程序,使用双重循环输出九九乘法表。
分析:由于需要输出9行9列的二维数据,因此需要使用双重循环,外层循环用于控制行数,内层循环用于控制列数。为了规范输出格式,可以使用print语句的格式控制输出方式。其中,“\t”的作用是跳到下一个制表位。

运行结果:


图3-7 三角形图案
【例3-20】 编写程序,使用双重循环输出如图3-7所示三角形图案。
分析:观察可知图形包含5行,因此外层循环执行5次;每行内容的由三部分组成:第一部分为输出空格,第二部分为输出星号,第三部分为输出回车等,分别通过两个for循环和一条print语句实现。

运行结果: