夜光序言:
剑客说,古风是一世天涯为伴、地庐穹背。
挽一朵剑花,斩一段红尘牵绊姻因缘。
正文:
2.7 循环的嵌套
2.7.1 夜光:目标
在一个复杂的程序中一个循环往往还包含另外一个循环,形成循环嵌套,循环嵌套有很
多规则,教学目标是要掌握这样规则,使用它编写找出 100 内所有素数之类的程序。
2.7.2 循环结构的嵌套
一个循环的循环语句可以是一个复合语句,在复合语句中又包含一个循环,这样就出现
了循环的嵌套。
例 2-7-1: 打印九九乘法表。
九九乘法表是两个数的乘积表,一个数是 i,它从 1 变化到 9,另一个数是 j,它从 1 变化到 9,这样输出 i*j 的值既为九九表的值,因此程序结构应该是两个循环,在一个确定的i 循环下,进行 j 循环,但为了不出现重复的 i*j 的值,可以设计 j 的值只从 1 变化到 i,程序如下:
for i in range(1,10):
for j in range(1,i+1):
print(i,"*",j,"=",i*j," ",end="")
print()
结果:
1 * 1 = 1
2 * 1 = 2 2 * 2 = 4
3 * 1 = 3 3 * 2 = 6 3 * 3 = 9
4 * 1 = 4 4 * 2 = 8 4 * 3 = 12 4 * 4 = 16
5 * 1 = 5 5 * 2 = 10 5 * 3 = 15 5 * 4 = 20 5 * 5 = 25
6 * 1 = 6 6 * 2 = 12 6 * 3 = 18 6 * 4 = 24 6 * 5 = 30 6 * 6 = 36
7 * 1 = 7 7 * 2 = 14 7 * 3 = 21 7 * 4 = 28 7 * 5 = 35 7 * 6 = 42 7 * 7 = 49
8 * 1 = 8 8 * 2 = 16 8 * 3 = 24 8 * 4 = 32 8 * 5 = 40 8 * 6 = 48 8 * 7 = 56 8 * 8 = 64
9 * 1 = 9 9 * 2 = 18 9 * 3 = 27 9 * 4 = 36 9 * 5 = 45 9 * 6 = 54 9 * 7 = 63 9 * 8 = 72 9 * 9 = 81
例 2-7-2: 找出 1~100 只间的所有素数。
在例 4_9 中已经知道怎样去判断一个整数 n 是否为素数,要找 1~100 之间的所有素数,
只要把 n 作为一个循环变量,从 1 循环到 100 为止就可以了,程序如下:
count=0
for n in range(1,101):
#flag 标志素数
flag=1
for m in range(2,n):
if n%m==0:
#如果能除尽,那么 n 不是素数,flag=0,退出 m 的内循环
flag=0
break
if flag==1:
print("%5d" % n,end="")
count+=1
if count%5==0:
print()
结果:
1 2 3 5 7
11 13 17 19 23
29 31 37 41 43
47 53 59 61 67
71 73 79 83 89 97
例 2-7-3: 打印出 1,2,3 的这样 3 个数字的所有排列。
for i in range(1,4):
for j in range(1,4):
for k in range(1,4):
if i!=j and j!=k and i!=k:
print(i,j,k)
结果:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
2.7.3 多循环的规则
多个循环存在时,只能并列或嵌套,不能出现交叉。
(1) 循环并列
既多个循环按前后顺序的关系出现在同一层上,例如以下的 i 循环与 j 循环的关系:
for i in range(10):
……
for j in range(10):
……
(2) 循环嵌套
既一个外层的循环套一个内层的循环,例如以下的 i 循环与 j 循环的关系:
for i in range(10):
……
for j in range(10):
……
(3) 循环交叉
既一个外层的循环与一个内层的交叉,例如以下的 i 循环与 j 循环的关系:
i=1;
while i<=9:
j=1
while j<=9:
print(i*j)
i=i+1
j=j+1
一般来说,一个程序中往往会出现多个循环的并列与嵌套的结构,而且嵌套可以有多层。
2.7.4 多循环的退出规则
如果由两个循环嵌套,那么内部循环执行 break 时仅仅是退出内部循环,不是退出外部循环,外部循环执行 break 时退出外部循环。
即 break 值退出它所在的那层循环,不会因为内部循环的一个 break 而使得循环整个撒循环都退出。例如:
i=1
while i<=3:
j=1
print("enter inner loop")
while j<=3:
print(i,j)
if j%2==0:
break
j=j+1
print("exit inner loop")
i=i+1
或者:
for i in range(1,4):
print("enter inner loop")
for j in range(1,4):
print(i,j)
if j%2==0:
break
print("exit inner loop")
程序执行结果:
enter inner loop
1 1
1 2
exit inner loop
enter inner loop
2 1
2 2
exit inner loop
enter inner loop
3 1
3 2
exit inner loop
由此可见 break 是退出内部的 j 循环,不是退出外部的 i 循环。
例 2-7-4:打印以下图案
*
***
*****
*******
我们常常见到的 print 函数在输出后就自动换行,实际上我们只要在输出函数中设置 end值就可以控制它不换行,例如:
print("*")
输出一个*后换行,但是:
print("*",end="")
输出*后不换行,在*输出后不做任何事情。这样:
for i in range(3):
print("*",end="")
print()
就连续输出 3 个*后才换行。
分析要输出的图形中有 4 行,*的数目为 1、3、5、7 个,即第 i(i=0,1,2,3)行有 2*i+1个*号,因此可以用两个循环完成:
for i in range(4):
for j in range(2*i+1):
print("*",end="")
print()
2.7.5 【案例】整数的素因素分解
1、案例描述
一个正整数分解质因数,例如:输入 90,打印出 90=2*3*3*5。
2、案例分析
对于任何一个整数 n,我们来找它的因数 i,如果 i 是它的因数,那么就不停分解这个 n为 i 的乘积,如果 i 不是因数那么就测试 i+1。这样的因数 i 一定为素数因素,因为如果 i 不是素数,那么 i=p*q 至少是两个整数的乘积(p,q>1),i 是 n 的因数,当然 p,q 也是 n 的因数,而循环到 i 之前,p,q 因数已经找完,因此不可能出现 i=p*q 还是 n 的因数。
3、案例代码
n=input("Enter an integer:")
n=int(n)
first=True
print(n,end="")
i=2
while i<=n:
while n%i==0:
if first:
print("=",i,end="")
first=False
else:
print("*",i,end="")
n=n//i
结果:
Enter an integer:43242
43242= 2* 3* 7207