十二、while循环
while:关键字 完成循环
完整结构如下:
while 条件:
语句体(块)
else:
语句体(块)
1、简单的while循环
根据上一篇博文中提到的for语句,我们知道想要打印1-10这是个数字,可以这么做:
for i in range(1,11):
print(i)
那如果想用while循环可以怎么写呢?我们来看看像下面这样是否可以成功运行呢?
while i <= 10:
print(i)
运行结果显示:nameerror,name ‘i’ is not defined.
我们提前声明一下变量,将代码改成下面这样试试:
i = 0
while i <= 10:
print(i)
点击运行,运行结果显示进入死循环,持续显示0,只有点击运行暂停,才会停止,这是为什么呢?
0
0
0
0
0
0
0
0
0
0
我们来分析一下这段代码,先走i=0这一句,紧接着拿着变量i去执行while i<= 10,拿着0和10进行比较(关系运算),0<= 10嘛?是的,这个条件是真的,则执行print(i),此时打印的i值为0.输出打印0之后,while这个循环体就执行完了,就会进入下一次的判断。如果判断条件成立,就会继续执行循环体里面的内容;如果条件不成立,就会跳出循环体。while这个关键字只要放到解释器里就认为是循环,就会拿着打印出来的值0再次进入循环体,循环往复,进入死循环,所以会出现上面的那种运行结果。
出现死循环的情况:
(1)打印变量,但是变量的值一直没有改变,上例中持续判断0是否小于等于10
(2)while后面的条件一直满足,就像上例中0一直<= 10
如何修正一下程序让它从死循环里面走出来呢?(打印1-10)
i = 1
while i <= 10:
print(i)
i += 1
print("打印完毕")
运行结果:当i=10时,满足 i <= 10,为true,所以可以打印出10。但是打印出10之后,执行 i += 1,此时i=11,将11拿进while语句进行条件判断,11>10,条件不成立,为false,故结束循环。
1
2
3
4
5
6
7
8
9
10
打印完毕
practice 1:打印1-30之间所有3的倍数
方式一:
i = 1
while i <= 30:
if i % 3 == 0:
print(i)
i += 1
print("打印完毕")
运行结果:
3
6
9
12
15
18
21
24
27
30
打印完毕
对于下面这个程序:
i = 1
while i <= 30:
if i % 3 == 0:
print(i)
运行的时候,光标持续闪动,但是无结果出来,实际上它是由一直在运行的,因为1<= 30,条件为true,之后进入循环,1% 3 不等于0,则无法打印i,再次进入循环体时还是i=1,相当于持续判断1是否整除3,所以光标持续闪动,程序也一直持续死循环,需要改变i的值才可以退出死循环,与上文打印1-10之间数字那段程序时有一样的弊病。
方式二:
n = 3
while n <= 30:
print(n)
n += 3
再考虑以下这种可以不可以?
n = 1
while n <= 30 and n % 3 == 0:
print(n)
n += 1
这种运行之后无结果,因为1<= 30成立,但是1% 3不等于0,true and false------>false,条件语句不成立,直接结束循环。故运行无果。将and改为or也不行,会将1-30 所有的数字都输出来。
可以写成下面这样:
方式三:
n = 3
while n <= 30 and n % 3 == 0:
print(n)
n += 3
但是这种写法比较不推荐。
practice 2:打印1-30之间所有既是3的倍数,又是5的倍数的数字。
print('$' * 30)
i = 1
while i <= 30:
if i % 3 == 0 and i % 5 == 0:
print(i)
i += 1
运行结果:
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
15
30
practice 3:使用while循环计算1-20的累加和。
sum = 0
i = 1
while i <= 20:
sum += i
i += 1
print(sum)
运行结果:(这是每加一次就会输出一次当前的sum值,sum 永远是拿上一次的计算结果参与到本次计算中)
1
3
6
10
15
21
28
36
45
55
66
78
91
105
120
136
153
171
190
210
若去掉print(sum)前面的缩进,则结果会直接显示1+2+3+…+20的最终结果:210
practice 4:打印三角形
'''
要求打印出如下形状:
*
**
***
****
*****
'''
在之前博文中提到过,三引号可以保持原样输出,所以下面这两种写法固然没错,但是如果*的数量更多呢?这么写会不会麻烦,而且代码冗余嘞?
print('''
*
**
***
****
*****
''')
print('*')
print('**')
print('***')
print('****')
print('*****')
博主分别用了for语句和while写了一下,而且运行成功啦。
for i in range(1, 6):
rightTriangle = '*' * i
print(rightTriangle)
i = 1
while i <= 5:
rightTriangle = '*' * i
i += 1
print(rightTriangle)
当然,还有另外的办法,此处涉及嵌套循环,在下一块具体介绍。
2、while循环嵌套
ceng = 1
while ceng <= 5:
count = 1
while count <= ceng:
print('*', end='')
count += 1
ceng += 1
print()
运行结果:
*
**
***
****
*****
分析一下这段代码的执行过程:
第一层:
ceng = 1:
while 1 <= 5:
count = 1
while 1 <= 1:
print('*')
第一层的执行是这样的流程
第一层执行结束以后,count += 1,此时的count=2, 2<= 1不成立,则会从这个while循环体跳出,执行处于同一级别的ceng += 1,进入第二层
第二层:(最后正确的那个程序的执行流程)
ceng = 2:
while 2 <= 5:
count = 1
while count <= ceng:(while 1 <= 2: 此时的层是2)
print('*',end='')--------》此时的图案变成 -----> *
*
打完星号之后做 count += 1的操作,现在count变为2,再去判断while 2 <= 2,满足条件,然后再执行print('*',end='')(这一句保证第二行打完一颗星之后不换行)
此时的图案变为 *
**
然后再执行count += 1的操作,现在count变为3,已经不满足<= 2的条件,开始执行下面层加一的操作,层;原来是2,现在加一之后,层变为3
层变为3之后,执行print()从而实现了换行 然后进入第三层
第三层:
ceng = 3
while 3 <= 5:
count = 1
while count <= ceng:(while 1 <= 3: 此时的层是3)
print('*',end='') 打一颗星
count += 1
count变为2,2<= 3,满足条件,打星,再count += 1,count变为3,
3<= 3,满足条件,打星,再count += 1,count= 4,不再满足小于等于3的条件,开始执行同一级别的ceng += 1的操作,使得层等于4
然后执行print(),实现换行
第四层第五层同理,不再赘述。
练习一下打印九九乘法表叭!
(因为九九乘法表打印出来也是直角三角形的样子,故与上例有异曲同工之妙)
i = 1
while i <= 9:
j = 1
while j <= i:
resault = i*j
print('{}*{}={}'.format(j, i, resault), end='\t')
j += 1
i += 1
print()
运行结果:
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
博主是这么写的,若有不妥,还请指正!