Topic 7.2 - while 循环的进阶用法¶
1. while 循环的嵌套¶
(1) while 循环的嵌套使用¶
while 循环也可以嵌套使用,即在一个 while 循环体内再包含另一个 while 循环,来实现更复杂的逻辑和功能。
嵌套 while 循环的基本语法如下:
while 条件1:
循环体1
while 条件2:
循环体2
循环体1的其他代码
- 在这段代码中,
循环体1是外层循环的代码块,循环体2是内层循环的代码块 - 当外层循环的条件
条件1为True时,进入外层循环体,执行循环体1的代码 - 当执行到内层
while 条件2:时,如果条件2为True,则进入内层循环体,执行循环体2的代码 - 当内层循环全部执行完毕后,程序会回到外层循环体,继续执行
循环体1的其他代码,然后重新评估外层循环的条件条件1 - 当外层循环来到第二圈时,内层循环又会从头重新开始执行一遍
我们来看一个简单的例子:
i = 0
while i < 3:
print("外层循环计数", i)
j = 0
while j < 2:
print(" 内层循环计数", j)
j = j + 1
i = i + 1
print("循环结束")
外层循环计数 0
内层循环计数 0
内层循环计数 1
外层循环计数 1
内层循环计数 0
内层循环计数 1
外层循环计数 2
内层循环计数 0
内层循环计数 1
循环结束
在这个例子中:
-
外层循环第1次判断时
i值为0,0 < 3为True,进入外层循环,然后打印外层循环计数 0,之后将j初始化为0- 内层循环第1次判断时
j值为0,0 < 2为True,进入内层循环,然后打印内层循环计数 0,之后将j增加1变为1 - 内层循环第2次判断时
j值为1,1 < 2为True,进入内层循环,然后打印内层循环计数 1,之后将j增加1变为2 - 内层循环第3次判断时
j值为2,2 < 2为False,退出内层循环,
回到外层循环体,之后将
i增加1变为1 - 内层循环第1次判断时
-
外层循环第2次判断时
i值为1,1 < 3为True,进入外层循环,然后打印外层循环计数 1,之后将j初始化为0- 内层循环第1次判断时
j值为0,0 < 2为True,进入内层循环,然后打印内层循环计数 0,之后将j增加1变为1 - 内层循环第2次判断时
j值为1,1 < 2为True,进入内层循环,然后打印内层循环计数 1,之后将j增加1变为2 - 内层循环第3次判断时
j值为2,2 < 2为False,退出内层循环,
回到外层循环体,之后将
i增加1变为2 - 内层循环第1次判断时
-
外层循环第3次判断时
i值为2,2 < 3为True,进入外层循环,然后打印外层循环计数 2,之后将j初始化为0- 内层循环第1次判断时
j值为0,0 < 2为True,进入内层循环,然后打印内层循环计数 0,之后将j增加1变为1 - 内层循环第2次判断时
j值为1,1 < 2为True,进入内层循环,然后打印内层循环计数 1,之后将j增加1变为2 - 内层循环第3次判断时
j值为2,2 < 2为False,退出内层循环,
回到外层循环体,之后将
i增加1变为3 - 内层循环第1次判断时
-
外层循环第4次判断时
i值为3,3 < 3为False,退出外层循环 - 程序继续执行
print("循环结束"),打印循环结束
(2) while 循环嵌套中的 break 和 continue¶
在嵌套的 while 循环中,break 和 continue 语句的作用范围仅限于它们所在的循环体:
break语句会终止它所在的最近一层循环,无法同时终止多层循环continue语句会跳过它所在的最近一层循环的当前迭代,进入下一次迭代,无法同时影响多层循环
我们来看一个例子:
i = 0
while i < 3:
print("外层循环计数", i)
j = 0
while j < 5:
print(" 内层循环计数", j)
if j == 2:
break
j = j + 1
i = i + 1
print("循环结束")
外层循环计数 0
内层循环计数 0
内层循环计数 1
内层循环计数 2
外层循环计数 1
内层循环计数 0
内层循环计数 1
内层循环计数 2
外层循环计数 2
内层循环计数 0
内层循环计数 1
内层循环计数 2
循环结束
这里我们可以看到,break 语句只终止了内层循环
- 当内层循环被
break终止后,程序回到外层循环体,继续执行外层循环 - 而外层循环并没有受到影响,继续进行下一次迭代
我们来看一个使用两个 break 语句,来分别终止内层和外层循环的例子:
i = 0
while i < 3:
print("外层循环计数", i)
j = 0
while j < 5:
print(" 内层循环计数", j)
if j == 2:
break
j = j + 1
if i == 1:
break
i = i + 1
print("循环结束")
外层循环计数 0
内层循环计数 0
内层循环计数 1
内层循环计数 2
外层循环计数 1
内层循环计数 0
内层循环计数 1
内层循环计数 2
循环结束
这里我们可以看到:
- 内层循环被
break终止后,程序回到外层循环体,继续执行外层循环 - 当外层循环的
i值为1时,触发外层循环的break语句,终止了外层循环
2. while 循环综合练习 - 打印九九乘法表¶
我们来看一个经典的 while 循环的例子:打印九九乘法表,我们期望的输出是:
1 * 1 = 1 1 * 2 = 2 2 * 2 = 4 1 * 3 = 3 2 * 3 = 6 3 * 3 = 9 1 * 4 = 4 2 * 4 = 8 3 * 4 = 12 4 * 4 = 16 1 * 5 = 5 2 * 5 = 10 3 * 5 = 15 4 * 5 = 20 5 * 5 = 25 1 * 6 = 6 2 * 6 = 12 3 * 6 = 18 4 * 6 = 24 5 * 6 = 30 6 * 6 = 36 1 * 7 = 7 2 * 7 = 14 3 * 7 = 21 4 * 7 = 28 5 * 7 = 35 6 * 7 = 42 7 * 7 = 49 1 * 8 = 8 2 * 8 = 16 3 * 8 = 24 4 * 8 = 32 5 * 8 = 40 6 * 8 = 48 7 * 8 = 56 8 * 8 = 64 1 * 9 = 9 2 * 9 = 18 3 * 9 = 27 4 * 9 = 36 5 * 9 = 45 6 * 9 = 54 7 * 9 = 63 8 * 9 = 72 9 * 9 = 81 我们先来分析以下这个问题的实现思路和关键问题:
- 乘法表有9行9列,每个单元格的格式都是
行号 * 列号 = 乘积 - 但是表格的右上角是空的,这个是如何实现的呢:我们会发现空的部分满足一个条件:列号 > 行号,我们可以在程序中加入这个判断
- 如果每一个算式对应一个打印的话,同一行中的算式并没有换行,这个是怎么做到的呢:这个就可以使用到
print函数的end参数 - 另外一个问题是:如何做到算式之间的对齐呢:这个可以使用到
\t转义字符
我们先尝试实现一个简单的版本,我们先不考虑对齐和右上角的问题,用 * 先来占位,打印一个 9 * 9 的表格:
- 首先我们要考虑,如何实现行和列的逻辑呢,这就要使用到嵌套
while循环了,外圈控制行,内圈控制列 - 其次,在打印行的时候,并没有换行,整个一行打印完毕才会换行,这就说明内圈中的
print是有end参数的,而换行是在外圈中实现的 - 我们来看代码:
row = 1
while row <= 9:
col = 1
while col <= 9:
print("*", end="")
col += 1
print()
row += 1
*********
*********
*********
*********
*********
*********
*********
*********
*********
接着我们把末尾的空字符串换成 \t,来实现对齐:
row = 1
while row <= 9:
col = 1
while col <= 9:
print("*", end="\t")
col += 1
print()
row += 1
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
接着,我们来实现右上角空白的逻辑:
- 右上角空白的逻辑是:列号 > 行号
- 那么左下角有数字的逻辑就是:列号 <= 行号
- 这样的话,内圈循环的判断条件就不再是
col <= 9了,而是col <= row了 - 我们来看代码:
row = 1
while row <= 9:
col = 1
while col <= row:
print("*", end="\t")
col += 1
print()
row += 1
*
* *
* * *
* * * *
* * * * *
* * * * * *
* * * * * * *
* * * * * * * *
* * * * * * * * *
最后,我们把 * 替换成 行号 * 列号 = 乘积 的格式,就大功告成:
row = 1
while row <= 9:
col = 1
while col <= row:
print(f"{col} * {row} = {col * row}", end="\t")
col += 1
print()
row += 1
1 * 1 = 1
1 * 2 = 2 2 * 2 = 4
1 * 3 = 3 2 * 3 = 6 3 * 3 = 9
1 * 4 = 4 2 * 4 = 8 3 * 4 = 12 4 * 4 = 16
1 * 5 = 5 2 * 5 = 10 3 * 5 = 15 4 * 5 = 20 5 * 5 = 25
1 * 6 = 6 2 * 6 = 12 3 * 6 = 18 4 * 6 = 24 5 * 6 = 30 6 * 6 = 36
1 * 7 = 7 2 * 7 = 14 3 * 7 = 21 4 * 7 = 28 5 * 7 = 35 6 * 7 = 42 7 * 7 = 49
1 * 8 = 8 2 * 8 = 16 3 * 8 = 24 4 * 8 = 32 5 * 8 = 40 6 * 8 = 48 7 * 8 = 56 8 * 8 = 64
1 * 9 = 9 2 * 9 = 18 3 * 9 = 27 4 * 9 = 36 5 * 9 = 45 6 * 9 = 54 7 * 9 = 63 8 * 9 = 72 9 * 9 = 81
我们通过打印九九乘法表,简单地体会了一下程序开发的几个关键要素:
- 需求分析:明确我们要实现什么功能,输出什么结果
- 逻辑设计:在写代码之前,先分析实现这个功能需要哪些步骤,如何使用程序结构来实现
- 版本迭代:从简单版本开始,逐步完善功能,最终实现目标