在之前的内容中,我们介绍了Python中的条件判断,它使得程序能够根据不同的条件执行不同的操作。在处理数据时,我们经常需要重复执行相同的步骤。循环(loop)的作用就是在条件满足的情况下,让指定的代码段不断重复执行,这是程序设计中非常重要的一种控制结构。我们可以使用循环来进行重复性的数据输入、处理和输出。
for
循环
单层 for
循环
for
和 in
是Python的关键字,它们之间放置我们自定义的变量,而 in
后面则可以跟一个序列(Sequence),循环会依次从序列中获取元素,并将其赋值给前面的自定义变量,然后执行循环体内的内容。
yaml
for x in sequence:
# 需要执行的操作
在 Python 中,有一种叫做列表(list)的数据结构,它的用法与其他编程语言中的数组(array)类似,关于列表的详细介绍,我们将在下一讲中详细说明。
列表使用中括号 []
将数字、字符串等元素包裹起来。例如,使用 [1, 2, 3, 4, 5]
这样的语法就可以创建一个包含 1、2、3、4、5 共 5 个元素的列表。下面是一个使用 for
循环将列表中的数据逐个打印出来的示例:
css
sequences = [0, 1, 2, 3, 4, 5]
for i in sequences:
print(i)
执行结果如下:
列表中的元素不仅限于数字,也可以是字符串或对象。在下面的示例中,列表就是由字符串构成的。
程序中用到 的len()
是Python的内置函数,它的作用是返回列表的长度;而theBeatles[i]
这样的语法,则是使用索引运算符 []
来获取列表中索引为 i
的元素。
scss
theBeatles = ['John Lennon', 'Paul McCartney', 'Ringo Starr', 'George Harrison']
for i in range(len(theBeatles)):
print(theBeatles[i])
执行结果如下:
当然,上面的程序也可以完全不使用 len()
函数和索引操作,程序反而会显得更为简洁且易于阅读。
ini
theBeatles = ['John Lennon', 'Paul McCartney', 'Ringo Starr', 'George Harrison']
for beatle in theBeatles:
print (beatle)
Python 的 for
循环语法有三个需要注意的重点:初始值、终止值,以及每次执行循环后控制变量递增或递减的变化。
在 Python 语言中,range()
函数可以高效地帮助我们创建一个整数序列,其用法为(起始值, 终止值, 递增(减)值)
,例如:
range(10) :生成从 0 到 9 的整数序列。
range(1, 11) :生成从 1 到 10 的整数序列(未指定递增值的情况下,其递增值默认为1)。
range(0, 10, 2) :生成从 0, 2, 4, 6, 8 的整数序列(递增值为2)。
简单来说,for
循环以固定数量的变量作为控制条件的依据,而利用 range()
函数,可以很方便地建立一个整数序列,让程序依照序列里的数值来执行循环体内的内容。
python
for i in range(10):
print(i, end=" ")
print() #换行
执行结果如下:
嵌套循环
嵌套循环的特性是在循环里面又包含了其他的循环。从外层循环来看,内层循环只是外层循环内要执行的一段程序而已;因此外层循环每动作一次,内层循环就会把整个循环执行一遍,执行完毕后才跳回到外层循环准备下一次的操作。
前面提到的单 层for
循环适用于单一控制变量的反复计算,这个控制变量的意义可以是循环执行的次数或是任意连续变化的物理量。如果现在面临的问题具有需要重复执行某段代码的特点,并且这段代码的执行受两个或更多个变量分别控制其变化时,采用嵌套循环(巢状循环)的方法编写程序以满足功能需求是最合适的做法。
九九乘法表共有九列九行的数据,其展示出来的形式是一个二维平面空间,因此这是一个非常适合使用两层嵌套循环结构来编写的案例:
python
for i in range(1, 10):
for j in range(1, 10):
if j == 9:
print("\t", i*j) # j == 9时,换行
else:
print("\t", i*j, end = '') # j < 9时,不换行
执行结果如下:
break
和 continue
循环的结束分为正常的结束和非正常的结束。正常的结束方式是当循环的判断条件不再符合时,循环自然结束;而不非正常的循环结束则是在循环自然结束前,我们已经得到想要的运算结果,利用强制中断的方式来结束循环。
Python 提供了两个指令,用来强制循环流程中断或跳过循环中的某些代码:
-
break
:中断循环的执行并跳出循环结构,继续执行循环外的代码。 -
continue
:不会让循环结束;只跳过continue
后面的剩余代码,接着继续执行下一次的循环。
也就是说,当程序执行到循环结构内的 break
语句时,break
语句会中断循环的执行,并且跳出循环结构,开始向下执行循环结构外的代码。因此,对于嵌套循环,若最内层执行到 break
语句时,则只会使最内层的循环结束,而不是跳出到整个嵌套循环结构外。
continue
语句与 break
语句之间有些相似,但它不会让循环结束。continue
语句会让程序跳出最靠近的这层循环,不再向下执行之后的代码,然后继续执行下一次的循环运行。因此它的目的是为了让程序不执行循环结构内的某些代码而已。
关于 break
语句和 continue
语句的差异示意图如下:
接下来这个程序的目的是利用 for
循环逐个打印出字符串中的字符内容,但当循环的变量变为字符 "u"
时,则中断循环的执行,立刻跳出循环:
bash
for i in "Hey Jude":
if i == "u":
break
print(i)
执行结果如下:
同样一个 for
循环程序,我们将 break
改成 continue
,其余不变;当循环的变量变为字符 "u"
时,程序只是跳过一次的循环,不执行continue
下一行的 print
语句;但循环并未结束,会在更新变量后继续执行下去:
bash
for i in "Hey Jude":
if i == "u":
continue
print(i)
执行结果如下:
while
循环
实际上,通过 for
循环可以处理的问题大概都可以改用 while
循环来处理;虽然两者之间的特性很类似,其适用范围还是有一点点差别的。
一般而言,for
循环比较适合在"已知循环次数"的问题上,而 while
循环则适合在"无法预知循环次数"的问题上。当程序需要不断地重复某些运算,直到出现指定的特殊状况时才停止,这种情况比较适合用 while
循环来实现。
while
循环在执行其内部代码之前,都会先检查条件判断式,如果其判断值为真(True),则执行循环体内的代码;否则就结束 while
循环。
例如两个人玩猜数字游戏,甲方心中默想一个数让乙方去猜,甲方就乙方所猜的数字口头提示"再大一点"或"再小一点",直到乙方猜中甲方心中默想的特定数字才停止,这样的游戏就属于无法预知循环次数的问题,相较于 for
循环,此问题会更适合使用 while
循环来实现。
while
循环的语法如下:
arduino
while test_expression:
Body of while
若我们要产生一笔 1, 2, 3, ..., 10
的序列,用 while
循环可以这样写:
ini
i = 1
while i <= 10:
print(i, end=" ")
i = i + 1
执行结果如下:
利用 while
循环计算1加到10的和,并将每次累加之后的值列印出来:
ini
sum = 0
i = 1
while i <= 10:
sum = sum + i
i = i + 1
print(sum, end= " ")
执行结果如下:
我们也可以使用 break
语句来中断 while
循环的执行。在本例中,while
后面的判断值为1,代表循环永远成立,会一直执行下去。但我们在循环内部加上 if
的判断条件和 break
语句,让循环可以在特定情况下结束执行。例如:
ini
sequences = [0, 1, 2, 3, 4, 5]
i = 0
while 1: #判断条件值为1, 代表循环永远成立
print(sequences[i], end = " ")
i = i + 1
if i == len(sequences):
print("全部打印完了")
break
执行结果如下:
打印出 1, 2, 3, ..., 10
的序列,但利用 continue
跳过 4
这个数字:
ini
i = 0
while i < 10:
i = i + 1
if i == 4:
continue
print (i, end = " ")
执行结果如下:
打印出 9, 8, 7, ..., 0
的序列,但利用 continue
跳过 4
这个数字:
ini
i = 10
while i > 0:
i = i - 1
if i == 4:
continue
print(i, end = " ")
执行结果如下:
透过合理的使用条件与循环,就能够写出很多很有用的程序了!