购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.5 循环语句

通过循环,可以使得某些语句重复执行多次。例如,要计算1~ n 的和,可以使用一个变量sum=0保存求和结果,并设置一个变量i,让其遍历1~ n n 个整数;对于i的每一个取值,执行sum+=i的运算;遍历结束后,sum中即保存了求和结果。

提示 “遍历”这个词在计算机程序设计中经常会用到,其表示对某一个数据中的数据元素按照某种顺序进行访问,使得每个数据元素会被访问且仅被访问一次。例如,对于列表ls=[1, 'Python', True]中的3个元素,如果按照某种规则(如从前向后或从后向前)依次访问了1、'Python'、True这3个元素,且每个元素仅被访问了一次,则可以说对列表ls完成了一次遍历。

循环语句的执行过程如图2-45所示。其中,语句序列1和语句序列3分别是循环语句前和循环语句后所执行的操作。循环条件判断和语句序列2构成了循环语句:只要满足循环条件,就会执行语句序列2;执行语句序列2后,会再次判断是否满足循环条件。

图2-45 循环语句执行过程

这里介绍Python的两种循环语句:for循环和while循环。

2.5.1 for循环

与C/C++语言不同,Python语言中的for循环用于遍历可迭代对象中的每一个元素,并根据当前访问的元素做数据处理,其语法格式为

变量依次获取可迭代对象中每一个元素的值,在语句序列中可以根据当前变量保存的元素值进行相应的数据处理。例如,代码清单2-28可以将一个列表中各元素的值依次输出。

表1-2 Python部分版本的信息

代码清单2-28执行完毕后,输出结果如图2-46所示。

图2-46 代码清单2-28的运行结果

再如,代码清单2-29可以将一个字典中各元素的键和值依次输出。

表1-2 Python部分版本的信息

代码清单2-29执行完毕后,输出结果如图2-47所示。

图2-47 代码清单2-29的运行结果

提示 使用for遍历字典中的元素时,每次获取的是元素的键,通过键可以再获取到元素的值。如代码清单2-29中,通过第2行代码,每次从d中获取一个元素的键并赋给循环变量k,因此,k依次被赋值为字符串'Python'、字符串'C++'和字符串'Java'。通过第3行代码中的d[k]则可以根据k的值依次获取每个元素的值,即d['Python']的值为1,d['C++']的值为2,d['Java']的值为3。

使用for循环时,如果需要遍历一个数列中的所有数字,则通常利用range函数生成一个可迭代对象。range函数的语法格式如下:

各参数的含义如下。

• beg:表示起始数值。

• end:表示终止数值,注意生成对象中不包含值为end的元素。

• step:表示步长,允许为负值。

提示

1.生成的可迭代对象中包含的元素依次为beg、beg+1×step、beg+2×step、…、beg+ k ×step(满足beg+ k ×step<end且beg+( k +1)×step≥end,即生成对象中不包含值为end的元素)。例如,range(1, 9, 2)生成的可迭代对象中包含的元素依次为1、3(即1+1×2)、5(即1+2×2)和7(即1+3×2),而不会包含值为9的元素。

2.step允许为负值。例如,range(5,-1,-2)生成的可迭代对象中包含的元素依次为5、3(即5+1×(-2))、1(即5+2×(-2))。

3.如果step省略,则默认以1为步长。例如,range(1, 5)生成的可迭代对象中包含的元素依次为1、2(即1+1×1)、3(即1+2×1)、4(即1+3×1)。

4.在step省略的情况下,如果beg也省略,则默认从0开始。例如,range(5)生成的可迭代对象中包含的元素依次为0、1(即0+1×1)、2(即0+2×1)、3(即0+3×1)、4(即0+4×1)。

代码清单2-30展示了range函数的使用方法。

表1-2 Python部分版本的信息

代码清单2-30执行完毕后,第1~4行代码分别按照对应注释中的描述输出结果,如图2-48所示。

图2-48 代码清单2-30的运行结果

提示 range函数返回的是一个可迭代对象,通过list可将该对象转换为列表。

代码清单2-31展示了1~ n 的和的计算方法。

表1-2 Python部分版本的信息

如图2-49所示,执行代码清单2-31,如果输入10,则输出55;如果输入100,则输出5050。

图2-49 代码清单2-31的运行结果

如果希望计算1~ n 之间所有奇数的和,则可以编写如代码清单2-32所示的程序。

表1-2 Python部分版本的信息

如图2-50所示,执行代码清单2-32,如果输入10,则输出25;如果输入100,则输出2500。

图2-50 代码清单2-32的运行结果

思考 如果希望计算1~ n 之间所有是3的倍数的数字的和,应该如何编写程序呢?如果要计算 n 的阶乘呢?

【思考题2-37】 已知有代码“for x in y:”,则y必然是一个( )。

A.可哈希对象

B.可迭代对象

C.列表对象

D.集合对象

【思考题2-38】 print(list(range(5)))的输出结果是否是[0, 1, 2, 3, 4]?

【编程练习2-4】 编写程序实现以下功能:输入一个大于0的整数n,表示有n元人民币(人民币有10元、5元和1元3种面额),将所有可能的情况及可能情况的总数输出。输出格式如下:每一行输出一种情况,先输出10元的张数,再依次输出5元和1元的张数,各张数之间用一个英文逗号分开;最后一行输出可能情况的总数。

【编程练习2-5】 编写程序实现以下功能:输入两个大于0的整数beg和end,计算beg到end之间(包括beg和end)的所有水仙花数并输出(水仙花数是一个三位整数,其值与各位数字的立方和相等)。如果beg到end之间不存在水仙花数,则输出not found。

2.5.2 while循环

Python中while循环的使用方法与C/C++语言类似,其语法格式为

当循环条件返回True时,则执行语句序列;执行语句序列后,再判断循环条件是否成立。例如,对于1~ n 的求和计算,也可以使用while循环实现,如代码清单2-33所示。

表1-2 Python部分版本的信息

如图2-51所示,代码清单2-33与代码清单2-31的功能完全相同。执行代码清单2-33后,如果输入10,则输出55;如果输入100,则输出5050。

图2-51 代码清单2-33的运行结果

如果希望使用while循环计算1~ n 之间所有偶数的和,则可以编写如代码清单2-34所示的程序。

表1-2 Python部分版本的信息

如图2-52所示,执行代码清单2-34后,如果输入10,则输出30;如果输入100,则输出2550。

图2-52 代码清单2-34的运行结果

思考 在代码清单2-34中,为什么第2行代码将i赋值为2?为什么第5行代码每次循环将i加2?

【思考题2-39】 下面程序的输出结果是( )。

A.0

B.4

C.5

D.-1

【编程练习2-6】 下面程序的作用是计算1~ n 的和,请改正程序中存在的错误。

【编程练习2-7】 下面程序的作用是计算 n !,请改正程序中存在的错误。

【编程练习2-8】 编写程序实现以下功能:输入一个大于0的整数 n ,计算1!+2!+…+ n !,并将计算结果输出到屏幕上。

2.5.3 索引

对于2.5.1节中的代码清单2-28,如果希望不仅获取每一个元素的值,而且能获取每一个元素的索引值,则可以改成如代码清单2-35所示的方式,即通过len函数获取可迭代对象中的元素数量,再通过range函数生成由所有元素的索引值组成的可迭代对象。

表1-2 Python部分版本的信息

代码清单2-35执行完毕后,输出结果如图2-53所示。

图2-53 代码清单2-35的运行结果

即先输出每个元素的索引值,再输出该元素的值。

除了代码清单2-35所给出的实现方式外,还可以通过一种更简洁的方式即利用enumerate函数来访问每个元素的索引,如代码清单2-36所示。

表1-2 Python部分版本的信息

代码清单2-36执行完毕后,输出结果与代码清单2-35完全相同,如图2-54所示。

图2-54 代码清单2-36的运行结果

enumerate函数的功能是将一个可迭代对象组成一个索引序列对象,利用这个索引序列对象可以同时获得每个元素的索引和值。

提示

1.通过list可以将enumerate函数生成的对象转换成列表,从而查看该对象中的每一个元素,如图2-55所示。可以看到,每个元素是一个元组,其第一个元素对应列表ls中每个元素的索引值,第二个元素对应列表ls中每个元素的值。

2.代码清单2-36中第2行代码的for循环,实际上是每次获取一个元组,并用元组的第一个元素为k赋值(即ls中每个元素的索引值),用元组的第二个元素为v赋值(即ls中每个元素的值)。

图2-55 enumerate函数生成的对象

enumerate函数还可以指定索引的起始值,如代码清单2-37所示。

表1-2 Python部分版本的信息

代码清单2-37执行完毕后,输出结果如图2-56所示。

图2-56 代码清单2-37的运行结果

思考 在代码清单2-37中,将“enumerate(ls, 1)”改为“enumerate(ls, 3)”,则程序执行完毕后会输出什么结果呢?

【思考题2-40】 已知t=(5, 10, 15),则list(range(len(t)))的输出结果是否是[1, 2, 3]?

2.5.4 break

break语句用于跳出for循环或while循环。对于多层循环的情况,break语句用于跳出它所在的最近的那层循环。例如,代码清单2-38的功能是求1~100之间的素数。

表1-2 Python部分版本的信息

代码清单2-38执行完毕后,输出结果如图2-57所示。

图2-57 代码清单2-38的运行结果

提示

1.在代码清单2-38的第9行代码中,将print函数的end参数设置为''(仅包含一个空格的字符串),表示将结束符由默认的回车改为一个空格,使得多个素数能够输出到同一行。

2.在代码清单2-38中,有两层循环:第1行的for循环是外层循环,第4行的while循环是内层循环。break语句位于这两层循环中,但离break语句最近的那层循环是第4行的while循环。因此,当n%i==0成立时,通过第6行的break语句会跳出while循环(即结束当前n值的素数判断),而不会跳出for循环(即不会结束后面n值的素数判断)。

3.如果n不是素数,则其必然可以写为n=a×b(a和b均为大于1的正整数)。令a<=b,则a×a<=n,即a小于或等于n的平方根。因此,在代码清单2-38的第2行代码中,可以计算n的平方根并取整数部分,得到m;在第4行代码中,只需要将循环变量i的取值上限设定为m;如果n不是素数,则必然可以找到一个小于或等于m的值,其可以整除n。通过这种方式,可以减少程序的计算代价。

注意 break语句只能用于跳出for循环或while循环,而不能用于跳出if语句。例如,代码清单2-39在IDLE中执行时会报如图2-58所示的错误信息“'break' outside loop”,即“break在循环之外”。

表1-2 Python部分版本的信息

图2-58 代码清单2-39的运行结果

思考 请分别结合n=5和n=10这两种取值情况,分析一下代码清单2-38中第2~9行代码的执行过程。

2.5.5 continue

continue语句用于结束本次循环并开始下一次循环。与break类似,对于多层循环的情况,continue语句作用于它所在的最近的那层循环。例如,代码清单2-40的功能如下:对于用户输入的每一个整数,判断其是否是3的倍数,如果是3的倍数则进行求和;当用户输入0时结束输入,并输出所有3的倍数的整数的求和结果。

表1-2 Python部分版本的信息

执行代码清单2-40时,依次输入10、15、20、25、30、0,则最后输出45(即15+30的结果),如图2-59所示。

图2-59 代码清单2-40的运行结果

提示

1.在代码清单2-40中,循环条件被设置为True。通常称这种循环为“永真循环”,即不可能通过条件不成立退出循环。对于这种永真循环,循环的语句序列中必然包含break等能跳出永真循环的语句。否则,将导致死循环,程序无法正常退出。

2.与break语句相同,continue语句只能作用于for循环或while循环,而不能作用于if语句。例如,代码清单2-41在IDLE中执行时会报如图2-60所示的错误信息“'continue' not properly in loop”,即“continue不在循环中”。

表1-2 Python部分版本的信息

图2-60 代码清单2-41的运行结果

2.5.6 else

for循环和while循环后面可以跟着else分支,当for循环已经遍历完列表中所有元素或while循环的条件为False时,就会执行else分支。例如,代码清单2-42给出了使用else进行素数判断的程序示例。

表1-2 Python部分版本的信息

如图2-61所示,执行代码清单2-42时,如果输入5,则会输出“5是素数”;如果输入10,则不会输出任何信息。

图2-61 代码清单2-42的运行结果

提示 如果是通过break语句跳出,则循环后的else分支不会执行。例如,代码清单2-42执行时,如果输入10,则for循环就会通过break语句跳出循环,此时就不会执行else分支下的第7行代码。

注意 Python通过缩进方式体现各语句的逻辑关系。由于else既可以用于for循环或while循环,也可以用于if语句,所以在使用时要特别注意else的缩进。例如,如果将代码清单2-42中第6行和第7行代码多加一层缩进,则会输出错误的结果,如代码清单2-43和图2-62所示。

表1-2 Python部分版本的信息

提示 虽然代码清单2-43执行时不会报错,但可能会输出不正确的运行结果,这说明程序中存在逻辑错误。对于逻辑错误,可以直接通过复查代码的方式找到错误原因,也可以通过程序调试的方式找到错误原因。

图2-62 代码清单2-43的运行结果

【思考题2-41】 用于跳出循环的命令是( )。

A.break

B.continue

C.else

D.pass

【思考题2-42】 用于结束本次循环并开始下一次循环的命令是( )。

A.break

B.continue

C.else

D.pass z4VchKwQ3Tz+Kswb7lhcIa2SBu9pChS/IeG7eLf9K1EnNHt5wJL9BgYRZIpVTO2o

点击中间区域
呼出菜单
上一章
目录
下一章
×