前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >开源图书《Python完全自学教程》6.5while循环语句

开源图书《Python完全自学教程》6.5while循环语句

作者头像
老齐
发布2022-07-06 15:54:33
8400
发布2022-07-06 15:54:33
举报
文章被收录于专栏:老齐教室

6.5 while 循环语句

for 循环必须以可迭代对象作为被循环的对象,while 循环则不同,它是依据一定的条件进行循环,即只要满足某条件,循环体中的语句“总跑着”。

6.5.1 基本格式

while 循环语句的基本格式是:

代码语言:javascript
复制
while <expression>:
    <statements>

如果 <expression> 的布尔值是 True ,则执行循环体内的语句块 <statements>——依然是以缩进标记语句块。

代码语言:javascript
复制
>>> n = 3
>>> while n > 0:
...     n -= 1
...     print(n)
...
2
1
0

在这段代码中,n 的初始值是 3 ,则 while 后的表达式 n > 0 的布尔值是 True ,于是执行下面的语句块。执行 n -= 1n 的值为 2 (见 print(n) 结果),n > 0 的布尔值还是 True ,继续执行循环体中的语句块,直到 n = 0 ,表达式 n > 0 的布尔值是 False ,停止循环。

再如:

代码语言:javascript
复制
>>> lst = ['java', 'python', 'julia']
>>> while lst:
...     print(lst.pop())
...
julia
python
java

依然要判断 while 后面的表达式 lst 的布尔值,因为在上一行定义了该列表不为空,故其布尔值是 True ,于是执行循环体中的语句块。lst.pop() 的功能是删除列表中最后的成员并返回删除对象,直到列表为空,其布尔值为 False ,则终止循环。

如果有兴趣在交互模式中输入下面的代码,会发现一个“神奇”的现象:

代码语言:javascript
复制
>>> while 1:
...     print("laoqi")
...

观察到了吗?不看到终端不停地打印 'laoqi' ,就很难体会到什么叫做“死循环”——“循环到死”,无法靠程序自身的控制终止循环,也称“无限循环”。要停止上述“死循环”,最简单的方法就是关掉终端窗口。

6.5.2 break 和 continue 语句

在 Python 关键词中,breakcontinue 两个关键词构成了两个语句:

  • break 语句:终止循环,并跳转到循环语句下面的语句;
  • continue 语句:跳过此语句后面的循环体中的其他语句,回到循环的开始,并评估是否满足循环条件。

这两个语句可以用于 while 循环,也可以用于 for 循环。以 while 循环为例,其作用效果如图6-5-1所示。

图6-5-1 brak 和 continue 语句

用 break 语句将前面“死循环”的程序改造如下:

代码语言:javascript
复制
#coding:utf-8
'''
whileloop.py
'''
n = 0
while 1:
    n += 1
    if n >= 3:       # (1)
        break
    print('laoqi')

print('loop end')    # (2)

执行效果:

代码语言:javascript
复制
% python whileloop.py 
laoqi
laoqi
loop end

对照程序代码和执行结果,当满足注释(1)时,即执行其下的 break ,从而避免无限循环,并跳转到循环语句下面的注释(2)。

下面写一个“猜数游戏”的程序,要求:(1)计算机随机生成一个100以内的正整数;(2)用户通过键盘输入数字,猜测计算机所生成的随机数。注意,用户的输入次数不进行限制。

相较于前述写过的程序,现在这个要求比较复杂,算是一个“大型程序”了。不过,不论面对多么复杂的程序,都要将需求分析清楚——本程序需求已明确,再针对需求制定实现策略。

  • 生成随机数:用标准库的 random 模块;
  • 获得用户输入的数字:用 input() 函数;
  • 实现不限次数的操作:用 while 循环语句;
  • 判断用户的输入是否等于生成的随机数:用 if 语句;
  • 猜中了终止循环:用 break 语句。

接下来的工作,就是运用已经学过的知识,将上述策略编写成可执行的程序。建议读者先自己编写,而后与下面的示例代码进行对照,取长补短。此处的代码示例仅仅是一种实现方式,并不是标准答案。

代码语言:javascript
复制
#coding:utf-8
'''
guessnumber.py
'''

import random
number = random.randint(1,100)
guess = 0
while True: 
    num_input = input("please input one integer that is in 1~100:") 
    guess += 1
    if not num_input.isdigit():
        print("Please input interger.") 
    elif int(num_input) < 0 or int(num_input) >= 100:
        print("The number should be in 1 to 100.") 
    else:
        if number == int(num_input): 
            print(f"OK, you’ve done well.It is only {guess} times.") 
            break
        elif number > int(num_input): 
            print("your number is smaller.") 
        else: 
            print("your number is bigger.")

执行此程序,想一想怎么猜?观察我的猜测过程:

代码语言:javascript
复制
% python guessnumber.py
please input one integer that is in 1~100:50
your number is bigger.
please input one integer that is in 1~100:25
your number is smaller.
please input one integer that is in 1~100:37
your number is smaller.
please input one integer that is in 1~100:44
your number is smaller.
please input one integer that is in 1~100:47
your number is bigger.
please input one integer that is in 1~100:46
your number is bigger.
please input one integer that is in 1~100:45
OK, you’ve done well.It is only 7 times.

这个猜的过程,其实运用了一种简单的算法——二分查找算法(Binary Search Algorithm)。当然,运气好了,随便输入一个就能猜中,“蒙着猜”毕竟耗费的时间不稳定,而运用二分查找算法,你可以估计出最坏的时间复杂度。

由图6-5-1可知,另外一个关键词发起的 continue 语句,会略过此后的语句,回到循环的初始判断行,例如:

代码语言:javascript
复制
#coding:utf-8
'''
whilecontinue.py
'''
a = 11
while a > 0:
    a -= 1
    if a % 2 == 0:
        continue  # (3)
        print(a)  # (4)
    else:
        print(a)  # (5)

还是先看调试结果,再解释必要的部分。

代码语言:javascript
复制
% python whilecontinue.py
9
7
5
3
1

在 while 循环语句块内,当 a 是偶数时,执行注释(3)的 continue 语句,依据图6-5-1所示,略过其后的注释(4),即不打印偶数,然后转到 while 循环的开始,满足条件即再自减 1 ,则 a 变为奇数,执行注释(5),将奇数打印出来。于是得到了上述只显示奇数的执行结果。

break 语句和 continue 语句不仅仅可以用在 while 循环中,也能用于 for 循环,其作用亦然。

代码语言:javascript
复制
>>> for i in range(10):
...     if i % 2 == 0:
...         continue
...         print(i)
...     else:
...         print(i)
...
1
3
5
7
9

这是 continue 语句在 for 循环中的应用举例,读者可以对照前述 whilecontinue.py 中的程序理解。

代码语言:javascript
复制
>>> for i in range(1, 10):
...     if i % 5 == 0:
...         break
...     else:
...         print(i)
...
1
2
3
4

注意,上述代码中的 range(1, 10) ——如果是 rang(10) 会是什么结果?为什么?

6.5.3 else 分支

在6.3.1节的图6-3-1中,显示 for 循环有一个可选的 else 分支。对于 while 循环,也可以有此分支,语法格式为:

代码语言:javascript
复制
while <expression>:
    statements
else:
    additional_statements

下面就以 while 循环为例,理解 else 分支的作用。例如:

代码语言:javascript
复制
>>> n = 5
>>> while n > 0:
...     n -= 1
...     print(n)
... else:
...     print("this is else")
...
4
3
2
1
0
this is else

对照程序和上面的语法格式,当 n 自减到 0 时,n > 0 的布尔值是 False ,即不再执行 while 循环,则开始执行 else 分支下的语句。这段程序中没有 break 中断循环——循环是寿终正寝的。不然,使用 break 语句让循环“夭折”,会如何?

代码语言:javascript
复制
>>> n = 5
>>> while n > 0:
...     n -= 1
...     print(n)
...     if n == 2:
...         break
... else:
...     print('this is else')
...
4
3
2

在6.5.2节中学习 break 语句的时候,图6-5-1中显示,遇到 break 后就跳到 while 循环后面的语句。上述程序结果说明,如果 while 后面有 else 分支, break 也会跳过它。

通过上述对比,了解了 else 分支的作用,但是,另外一个问题就来了,如果写成:

代码语言:javascript
复制
while <expression>:
    statements

additional_statements

与上面包含 else 分支的语法有什么区别?

通过含有 break 的程序,就能看出区别:如果不使用 else 分支,additional_statements 的语句会总被执行,哪怕循环“夭折”也会执行。

事实上, else 分支在 while 循环中并非必要,Python 发明者吉多·范罗索姆甚至想剔除 while 的 else 分支。

在 for 循环中,else 分支会有如何表现?看下面的示例:

代码语言:javascript
复制
#coding:utf-8
'''
filename: forelse.py
'''
nums = [60, 70, 30, 110, 90]
found = False
for n in nums:
    if n > 100:
        found = True
        print("There is a number bigger than 100")
        break

if not found:     # (6)
    print("Not found!")

判断列表 nums 中是否有大于 100 的整数,若有,则 found = True ,并执行 break 结束循环。那么,此时注释(6)的条件就不满足了。否则,如果列表 nums 中没有使 n > 100 成立的整数,则 found = Fasle ,注释(6)的条件语句就会执行。显然,程序中的 found 就相当于一个“开关”(常说的“flag”)。如果用 else 分支,则可以省掉这个“开关”。

代码语言:javascript
复制
nums = [60, 70, 30, 110, 90]
for n in nums:
    if n > 100:
        print("There is a number bigger than 100")
        break
else:
    print("Not found!")

之所以能省掉 found ,也是因为循环被 break 后,else 分支不再执行。若修改 nums 中的数值,使 if n > 100 语句不执行,当循环完毕,则执行 else 分支——读者可以自行测试。由此可见,else 分支不论在 while 循环还是 for 循环,执行它的条件都是一样的。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老齐教室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 6.5 while 循环语句
    • 6.5.1 基本格式
      • 6.5.2 break 和 continue 语句
        • 6.5.3 else 分支
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档