[ 导读 ]本文重点讲述for语句和while语句。for语句属于遍历循环,while语句属于当型循环。除了两个循环语句外,还介绍了break、continue与pass三个用于控制循环结构中的程序流向的语句。在此基础之上,也介绍了列表推导式,这是一种特殊的循环语句。
循环语句又称为重复结构,用于反复执行某一操作。面对大数量级的重复运算,即使借助计算机,重复编写代码也是费时的,这时就需要借助循环语句。使用循环语句一般要用到条件判断,根据判断式的返回值决定是否执行循环体。
循环分为两种模式,一种是条件满足时执行循环体,另一种则相反,在条件不满足时执行循环体。前者称为当型循环,后者称为直到型循环。
在图1中,虚线框内是一个当型循环结构,此结构包含判断条件和循环体,以及连接各部分的流向线。程序执行时,先判断条件的真假。判断为真时,则执行循环体;判断为假时,不再执行循环体,循环结束。当型循环先进行条件判断,如果满足循环条件,再执行循环体,因此又被称为前测试型循环。
![c45479d893a65f26da4ad4e22b6a7e30.png](https://i-blog.csdnimg.cn/blog_migrate/b1dfbf72a66012f012b3eb5e0982d8b5.jpeg)
在图2中,虚线框内是一个直到型循环结构,此结构包括判断条件和循环体,以及连接各部分的流向线。程序执行时,先执行一次循环体,再判断执行循环的结果是否满足判断条件。满足条件时,再次执行循环体;不满足条件时,不再执行循环体。直到型循环在执行判断前先进入循环体运行,因此又被称为后测试型循环。
![29d4afe2bce924f68b009e92d6731304.png](https://i-blog.csdnimg.cn/blog_migrate/e7162f67abd9ac3a28f5a48902aae33d.jpeg)
Python中主要有两种循环语句,即for语句和while语句。前者采用遍历的形式指定循环范围,后者视判断式返回值的情况而决定是否执行。要更灵活地操纵循环的流向,就要用到break、continue和pass等语句。
01 for
for循环是迭代循环,在Python中相当于一个通用的序列迭代器,可以遍历任何有序序列,如str、list、tuple等,也可以遍历任何可迭代对象,如dict。不同于C语言,Python中的for语句将遍历系列中的所有成员,遍历顺序为成员在系列中的顺序。需要注意,在for循环中改变任何序列的内容都是危险的!
for语句不属于当型循环或直到型循环,它遍历序列对象内的元素,对每个元素运行一次循环体,循环的步数在程序开始执行时已经指定,不属于条件判断。
在for语句中,for和in搭配组成for-in循环结构,for-in循环依次把list或tuple中的每个元素迭代出来。for语句的基本语法格式如下:
![cf4680a132b4a8b26c2c57c4a0c5fd9d.png](https://i-blog.csdnimg.cn/blog_migrate/1de9572f54f9b5342ebc1de484e2eaf6.png)
for语句常用的语法格式及其参数说明如下所示:
![3e859a78663ec57b530888a8f76401ab.png](https://i-blog.csdnimg.cn/blog_migrate/e23c2d893aeee9e260092023b56b7a1d.png)
程序的执行从“for变量in序列”开始,该语句把序列中的每个元素代入变量,执行一遍操作语句1,重复的次数就是序列中元素的个数。
为了展示for循环的遍历功能,依次打印list中的姓名,如代码清单1所示。
代码清单1:for语句遍历提取str
![482ced6e09d43d9b50cd3e06d4f3d28c.png](https://i-blog.csdnimg.cn/blog_migrate/bdee3c8eea8b2c7809e312f91998d40a.jpeg)
输出结果:
![9c379a413cf96dc8f5fa9cfc1e0d7ae8.png](https://i-blog.csdnimg.cn/blog_migrate/de54c8a09b726e078e9fcc4239369dba.jpeg)
for语句同样可以实现dict的遍历方法,如代码清单2所示。
代码清单2:for语句遍历查询dict
![abde79bfb5bf1f0f448f48fadcae9ffd.png](https://i-blog.csdnimg.cn/blog_migrate/a7d187f7503e3f95c27ee4350c9649c1.jpeg)
输出结果:
![8ccc3a0709f68c584cf8c85b911db8c1.png](https://i-blog.csdnimg.cn/blog_migrate/6031c85c7a35db9357c1dcc9d416babe.jpeg)
从代码清单2可以看到,for语句中用于遍历的“变量”不仅可以是Python默认的指代词,也可以是常规的变量。
和条件语句一样,循环语句也可以使用嵌套,作用同样是丰富程序的功能性。设计一个成绩录入系统,就必然要录入姓名和课程这两类信息,仅靠一层循环是无法实现的,可使用两层循环结构,如代码清单3所示。
代码清单3:嵌套for语句
![07da42e49225a60c953b9511588e083b.png](https://i-blog.csdnimg.cn/blog_migrate/70b51467cd6dab34216e8437e93168cb.jpeg)
输出结果:
![6b52f59ea32b15bd8d687a2450d666ce.png](https://i-blog.csdnimg.cn/blog_migrate/dd1d930e55f40bc59ad1f3a40f7d04e6.jpeg)
理论上,for循环也可以无限嵌套,但并不推荐。
02 while
while语句是Python中最常用的递归结构。区别于for循环,while循环结构包含条件判断式,是一种条件循环,属于当型循环。
while语句最基本的形式包括一个位于顶部的布尔表达式,一个或多个属于while代码块的缩进语句。也可以在结尾处包含一个else代码块,它与while代码块是同级的,组成while-else的形式。while语句的基本语法格式如下。
![e2f557d850e79459c01a88fce9cf6b5d.png](https://i-blog.csdnimg.cn/blog_migrate/05b6c0732518ef0640900199c205afe0.jpeg)
while语句常用的参数及其说明如下所示:
![1cc7780732c814a1ed5f595f1f70414b.png](https://i-blog.csdnimg.cn/blog_migrate/f656bd0a7e350dcc37e3232d63653a5d.png)
执行while语句时,只要顶部的条件表达式返回真值,就一直执行while部分嵌套的递归代码,当条件表达式返回假值时,不再执行操作语句,程序跳出while结构。
while语句的基础使用方法如代码清单4所示。
代码清单4:while语句
![a52f5d25a3d45d563101492fcb79bc02.png](https://i-blog.csdnimg.cn/blog_migrate/f0064ce194c687340273b8c624f1511a.jpeg)
如果布尔表达式不带有<、>、==、!=、in、not in等运算符,仅仅给出数值之类的条件,也是可以的。当while后写入一个非零整数时,视为真值,执行循环体;写入0时,视为假值,不执行循环体。也可以写入str、list或任何序列,长度非零则视为真值,执行循环体;否则视为假值,不执行循环体。
如果布尔表达式始终返回1,while语句就变成无限循环,如代码清单5所示。
代码清单5:while语句无限循环
![576529efa874ae6d50c031bc6b5d2245.png](https://i-blog.csdnimg.cn/blog_migrate/baf39f0bc34632d6f3707dfd0ca785bc.jpeg)
![0337b863ad4308bd5d780829601b3f34.png](https://i-blog.csdnimg.cn/blog_migrate/9a70468df6b0adabf57b429b9f13b29f.jpeg)
运行代码清单5,将会不断打印出“循环”。代码清单5展示了制造无限循环的两种方式,既可以在while后写入一个固定的真值,也可以写入一个一直生成真值的表达式。要终止无限循环,可以使用快捷键Ctrl+C中断循环的执行,也可以用循环终止语句,这将在下文中介绍。
灵活地利用while语句中的布尔表达式及代入表达式的递归值,可以实现特别的功能,如代码清单6所示。
代码清单6:while语句实现str截取
![e8d32cda7a3ef1a7fb2cafb04ad43cce.png](https://i-blog.csdnimg.cn/blog_migrate/d5ab8de1586b1eb50a92a2d61138354e.jpeg)
代码清单6包含一个自减迭代值,它并不通过明显的运算符实现自减,而是利用索引法则,x变量一直从str中第2个值截取至结尾,每次都将位于str最前面的字符截取掉,最终只剩下一个字符时,再次截取就只有空的结果,布尔表达式返回0,循环终止。
通过代码清单5和代码清单6可以看到,灵活地利用递归式,可以实现程序流向的控制。
while循环同样可以使用嵌套,嵌套的while循环实现成绩录入系统如代码清单7所示。
代码清单7:嵌套while语句
![e13657e94351f028ae099a1fdfeb60e0.png](https://i-blog.csdnimg.cn/blog_migrate/0ed16393600f43b5669adf6b636d6589.jpeg)
输出结果:
![71a7be1a767955d5829cc8e774645f5f.png](https://i-blog.csdnimg.cn/blog_migrate/086e003e201b7c9edc0886925bdce31d.jpeg)
代码清单7的第1层while语句用于录入人名,第2层则在各人名下录入多门成绩,布尔表达式决定录入的人数和课程数。
03 break、continue与pass
在前两节中,已经介绍了Python中的两种循环语句。循环语句中还可以嵌入break、continue和pass语句,以灵活地改变流向,实现更多功能。
1. break
在Python中,break语句用于终止循环语句的执行。使用该语句时,即使循环条件判断为真,或序列未被完全递归,循环语句也会被立刻停止。
break语句一般配合条件判断使用,因为程序的终止必须是在某一条件被满足时执行。break语句在for循环和while循环中的使用如代码清单8所示。
代码清单8:break语句的使用
![9d34a6495699c8e357a64c1e071cde4a.png](https://i-blog.csdnimg.cn/blog_migrate/3c2ad9882c9b8d36620afe1826ea4fc3.jpeg)
输出结果:
![b608589a9b2fc66a215b8b8f5e060632.png](https://i-blog.csdnimg.cn/blog_migrate/49ae0e161ccb258c7a3c88d231bfc1cf.jpeg)
![cbb52ac5f5d6c7d23c57c89ac100b79c.png](https://i-blog.csdnimg.cn/blog_migrate/6ceab9eea69e68d56029587982833ad4.jpeg)
输出结果:
![6c19d7bdd80e9652841637fc1655fe86.png](https://i-blog.csdnimg.cn/blog_migrate/cc0ca25c854941f0ac248407419f5248.jpeg)
从代码清单8可以看到,break语句用于for循环和while循环是有区别的。用于for循环时,只终止遍历中某一次的循环体执行;用于while循环时,整个循环被终止。
break只终止本层循环,如有多层嵌套的循环,在其中一层循环中写入break,只在这层循环中生效,程序将跳到上一层循环中继续运行,如代码清单9所示。
代码清单9:break语句用于嵌套循环结构
![63a3a2df31965c79031b3d810d458f03.png](https://i-blog.csdnimg.cn/blog_migrate/f9c182910ed9b645fb9f1e570cf5f7b4.jpeg)
输出结果:
![844b46720de34b5f9475bce64081560b.png](https://i-blog.csdnimg.cn/blog_migrate/1664fbfcc8f08d11ad245ebeda7b0f10.jpeg)
在代码清单9中,break语句在条件判断式“if j>1:”后被使用,因此尽管j的指定遍历次数为10,实际上遍历只运行两次。由于break语句只终止本层循环的运行,i依旧遍历执行了两次,而不是在第1次遍历过程末尾终止。
2. continue
Python中的continue语句用于跳出当前循环,并执行下一次循环,而break跳出整层循环,两者的功能具有明显区别。
如果一段代码中包含continue语句,循环执行至continue处时,先忽略本次循环,在本层仍满足条件的剩余循环次数中继续执行,不会终止这一层循环。实际上,如果在某一层的每次循环中都使用continue语句,就相当于使用break语句。
打印一个数表,要不打印某些指定的数字,或只打印某类数,就可以使用continue语句跳过一些循环次数,该语句在for循环和while循环中都可以自由地使用,如代码清单10所示。
代码清单10:continue语句用于循环结构
![9fb1e22eb9e0c14e7e8d3a40db030942.png](https://i-blog.csdnimg.cn/blog_migrate/479fc3eef46e30dc3c336095fb39071a.jpeg)
![d124cf3913368b7629b095d61e971d43.png](https://i-blog.csdnimg.cn/blog_migrate/e35b2d145f6139dabcc52dbb3e573962.jpeg)
break语句一旦用于嵌套循环中的第n层,该层循环会被终止,但在执行第n-1层循环时,仍会创造一个第n层循环并执行。continue语句同样如此,只是仍会执行某一层的剩余部分。因此,无论使用哪种循环终止语句,都只会影响使用终止语句的那一层循环,而不会干扰到其他层。continue语句用于循环的例子如代码清单11所示。
代码清单11:continue语句用于嵌套循环结构
![82942db5c908b2fe7541ae4d09cb7856.png](https://i-blog.csdnimg.cn/blog_migrate/1f0022c15ba8b581107f09e0076d5168.jpeg)
输出结果:
![764b96f317ca02fa3427c5dc2e5cd408.png](https://i-blog.csdnimg.cn/blog_migrate/87ffcecb02880798d7872071a516b056.jpeg)
3. pass
pass是空语句,不做任何操作,只起到占位的作用,其作用是为了保持程序结构的完整性。尽管pass语句不做任何操作,但如果暂时不确定要在一个位置放上什么样的代码,可以先放置一个pass语句,让代码可以正常运行。pass语句并非循环或者条件语句的一部分,但与break、continue在代码形式上有些类似。
使用pass语句遍历输出str及数值计算,如代码清单12所示。
代码清单12:pass语句
![6d37444d992dc4c5909a01cd5f96df85.png](https://i-blog.csdnimg.cn/blog_migrate/063c0069485bf7e74cee058548affdc9.jpeg)
输出结果:
![b501c25cc4c61b885c2a00bd50b27a25.png](https://i-blog.csdnimg.cn/blog_migrate/7da8bcc95cee5cf658519b67478f7aab.jpeg)
![7633dca86355a8b647383c231b811063.png](https://i-blog.csdnimg.cn/blog_migrate/44d64bf75e10b09c814e38d6b66a843a.jpeg)
输出结果:
![9db5a958c8d8c67721d81b4f0173a03b.png](https://i-blog.csdnimg.cn/blog_migrate/3321bc236e164c639c14460ca27fc91e.jpeg)
从代码清单12可以看到,Python在“P”和“t”之间占位,当循环遍历到“y”时不做任何操作;当i等于3时,幂运算不执行,但不影响其他数值。上述两个代码如果在pass的位置缺失,程序将无法执行,因为判断条件没有给出相应的执行语句,会导致逻辑出错。使用pass语句占位,一方面为了让程序正常执行,另一方面也是为了方便以后补充操作语句。
04 列表推导式
推导式是可以从一个数据序列构建另一个新的数据序列的结构体,能够非常简洁地构造新的变量。列表推导式是其中最常用的类型。
列表推导式又称为列表解析式,是Python迭代机制的一种应用,也是一种高效创建列list的方式,可以动态地创建list。由于列表推导式必须用到遍历循环,因此属于一种特殊的循环。
使用列表推导式时,需要将推导式写在[]中。list中的元素可以来源于其他类型序列、可迭代对象或自建的满足一定条件的序列。使用列表推导式的好处是代码更加简洁,实现效率更高。
列表推导式的基本语法格式如下:
[操作语句 for变量 in 序列 if 条件表达式]
列表推导式常用的参数及其说明如下所示:
- 操作语句:接收操作语句,表示执行一段代码。无默认值
- 条件表达式:接收布尔表达式,表示判断条件是否成立。无默认值
- 序列:接收序列,表示遍历范围。无默认值
列表推导式可以不包含条件表达式,只做遍历,生成list,如代码清单13所示。
代码清单13:使用列表推导式生成list
![2b1f95a50f4da6b3685965f9dda0d754.png](https://i-blog.csdnimg.cn/blog_migrate/4db74b265435c11f86b8b6ba3a559b4f.png)
输出结果:
![e7cb3979e5e5893605962bc3e789e0c2.png](https://i-blog.csdnimg.cn/blog_migrate/342bef35ce87a84795421e5239bc95e3.jpeg)
在代码清单13中,除了列表推导式的简单形式,还说明了列表推导式中可以使用多样的函数和变量类型。另外,列表推导式中也可以包含条件语句,如代码清单14所示。
代码清单14:包含条件语句的列表推导式
![f4f0246b82a7183f1d2024a534f68303.png](https://i-blog.csdnimg.cn/blog_migrate/568e722fe45602b087daa5642d7253d2.jpeg)
列表推导式最大的优点还是简洁,这需要与常规的编程方式进行对比。如代码清单15所示,要创建一个平方数组成的list,这里的两种方式是等价的,但列表推导式的方式显然代码更加简洁。
代码清单15:常规方式与列表推导式对比
![857f201628678fc33e2a0ca60a603b5f.png](https://i-blog.csdnimg.cn/blog_migrate/67d752cc5399602411466c973ca934e7.jpeg)
![86d117b24087fbd198456b9181ecac1e.png](https://i-blog.csdnimg.cn/blog_migrate/361bcc07b1c31b4cf56381faa3984721.jpeg)
列表推导式中同样可以实现嵌套循环,如代码清单16所示。
代码清单16:包含嵌套循环的列表推导式
![bc85b5337660d770a8f19b070bc7a288.png](https://i-blog.csdnimg.cn/blog_migrate/0a4ea3e554b7c4f03b23063c12cd810c.jpeg)
![6e41dedd43c688a23e459d6a9c0f47c3.png](https://i-blog.csdnimg.cn/blog_migrate/a12cbdebd41ea89de38e461371e438f8.jpeg)
代码清单16所示的列表推导式将两个不同list中的元素整合到了一起。列表推导式中包含一对括号,在括号中有一个表达式,表达式后面紧跟一条for语句,然后是零条或多条for语句或if语句。通过for语句和if语句计算出表达式,结果作为新list的元素。