16 KiB
python“while”循环(无限迭代)
*立即观看**本教程有真实 Python 团队创建的相关视频课程。和书面教程一起看,加深理解: 掌握 While Loops
迭代意味着一遍又一遍地执行同一个代码块,可能是多次。实现迭代的编程结构被称为循环。
在编程中,有两种类型的迭代,不定迭代和确定迭代:
-
使用无限迭代,循环执行的次数没有事先明确指定。相反,只要满足某些条件,就重复执行指定的块。
-
使用确定迭代,指定块将被执行的次数在循环开始时被明确指定。
在本教程中,您将:
- 了解
while循环,这是用于无限迭代的 Python 控制结构 - 了解如何提前脱离循环或循环迭代
- 探索无限循环
完成后,你应该很好地掌握了如何在 Python 中使用无限迭代。
免费奖励: ,它向您展示 Python 3 的基础知识,如使用数据类型、字典、列表和 Python 函数。
***参加测验:***通过我们的交互式“Python”while“Loops”测验来测试您的知识。完成后,您将收到一个分数,以便您可以跟踪一段时间内的学习进度:
*参加测验
while循环
让我们看看 Python 的while语句是如何用来构造循环的。我们将从简单开始,然后不断修饰。
基本while循环的格式如下所示:
while <expr>:
<statement(s)>
<statement(s)>表示要重复执行的块,通常称为循环体。这用缩进来表示,就像在一个语句中一样。
**记住:**Python 中所有的控制结构都是用缩进来定义块的。参见前面教程中关于分组语句的讨论进行回顾。
控制表达式<expr>通常包含一个或多个变量,这些变量在开始循环之前被初始化,然后在循环体的某个地方被修改。
当遇到while循环时,首先在布尔上下文中评估<expr>。如果为真,则执行循环体。然后再次检查<expr>,如果仍然为真,则再次执行主体。这一直持续到<expr>变为假,此时程序执行继续到循环体之外的第一条语句。
考虑这个循环:
1>>> n = 5
2>>> while n > 0:
3... n -= 1
4... print(n)
5...
64
73
82
91
100
以下是本例中发生的情况:
-
n最初是5。第 2 行的while语句头中的表达式是n > 0,这是真的,所以循环体执行。在第 3 行的循环体内,n从1递减到4,然后打印出来。 -
当循环体结束时,程序执行返回到循环顶部的第 2 行,并再次计算表达式。还是真的,所以主体再执行一次,打印出
3。 -
这一直持续到
n变成0为止。此时,当表达式被测试时,它是假的,并且循环终止。执行将在循环体后面的第一条语句处继续,但在本例中没有这样的语句。
注意,在发生任何事情之前,首先测试的是while循环的控制表达式。如果一开始就为 false,循环体将永远不会被执行:
>>> n = 0
>>> while n > 0:
... n -= 1
... print(n)
...
在上面的例子中,当遇到循环时,n就是0。控制表达式n > 0已经为假,所以循环体永远不会执行。
这里是另一个while循环,涉及一个列表,而不是一个数字比较:
>>> a = ['foo', 'bar', 'baz']
>>> while a:
... print(a.pop(-1))
...
baz
bar
foo
当在布尔上下文中评估一个列表时,如果列表中有元素,则为 true,如果列表为空,则为 falsy。在这个例子中,a只要包含元素,就是真的。一旦用.pop()方法移除了所有的条目并且列表为空,a为假,循环终止。
Python 的break和continue语句
到目前为止,在您看到的每个例子中,while循环的整个主体都在每次迭代中执行。Python 提供了两个关键字,可以提前终止循环迭代:
-
Python
break语句立即终止整个循环。程序执行到循环体后面的第一条语句。 -
Python
continue语句立即终止当前循环迭代。执行跳转到循环的顶部,重新计算控制表达式以确定循环是再次执行还是终止。
下图展示了break和continue之间的区别:
这里有一个名为break.py的脚本文件,它演示了break语句:
1n = 5
2while n > 0:
3 n -= 1
4 if n == 2:
5 break 6 print(n)
7print('Loop ended.')
从命令行解释器运行break.py会产生以下输出:
C:\Users\john\Documents>python break.py
4
3
Loop ended.
当n变为2时,执行break语句。循环完全终止,程序执行跳转到第 7 行的 print()语句。
**注:**如果你的编程背景是在 C 、 C++ 、 Java ,或者 JavaScript ,那么你可能会疑惑 Python 的 do-while 循环在哪里。坏消息是 Python 没有 do-while 结构。但是好消息是,您可以使用一个带有break语句的while循环来模拟。
下一个脚本continue.py,除了用continue语句代替了break之外,其他都是一样的:
1n = 5
2while n > 0:
3 n -= 1
4 if n == 2:
5 continue 6 print(n)
7print('Loop ended.')
continue.py的输出如下所示:
C:\Users\john\Documents>python continue.py
4
3
1
0
Loop ended.
这一次,当n为2时,continue语句导致迭代终止。因此,2不会被打印。执行返回到循环的顶部,重新计算条件,并且仍然为真。循环继续,当n变成0时终止,如前所述。
else条款
Python 允许在一个while循环的末尾有一个可选的else子句。这是 Python 独有的特性,在大多数其他编程语言中没有。语法如下所示:
while <expr>:
<statement(s)>
else:
<additional_statement(s)>
else子句中指定的<additional_statement(s)>将在while循环终止时执行。
现在,你可能会想,“这有什么用?”您可以通过将这些语句直接放在while循环之后,而不使用else来完成同样的事情:
while <expr>:
<statement(s)>
<additional_statement(s)>
有什么区别?
在后一种情况下,如果没有else子句,<additional_statement(s)>将在while循环终止后执行,无论如何。
当<additional_statement(s)>被放在else子句中时,只有当循环“因穷尽”而终止时,它们才会被执行——也就是说,如果循环迭代,直到控制条件变为假。如果循环被一个break语句退出,那么else子句将不会被执行。
考虑下面的例子:
>>> n = 5
>>> while n > 0:
... n -= 1
... print(n)
... else: ... print('Loop done.') ...
4
3
2
1
0
Loop done.
在这种情况下,循环重复,直到条件用尽:n变成0,所以n > 0变成假。因为循环过了它的自然寿命,可以这么说,所以执行了else子句。现在观察这里的区别:
>>> n = 5
>>> while n > 0:
... n -= 1
... print(n)
... if n == 2: ... break ... else:
... print('Loop done.')
...
4
3
2
这个循环因break而提前终止,所以else子句没有被执行。
看起来似乎单词else的含义不太适合while循环,也不太适合if陈述。Python 的创造者吉多·范·罗苏姆曾说过,如果让他重来一次,他会把while循环的else子句从语言中删除。
以下解释之一可能有助于使其更加直观:
-
把循环的头(
while n > 0)想象成一个被反复执行的if语句(if n > 0),当条件变为假时,else子句最终被执行。 -
把
else想象成nobreak,因为如果没有break,后面的块就会被执行。
如果你觉得这两种解释都没有帮助,那就忽略它们吧。
while循环中的else子句什么时候有用?一种常见的情况是,您正在搜索特定项目的列表。如果找到了该项,您可以使用break退出循环,并且else子句可以包含在没有找到该项时要执行的代码:
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> s = 'corge'
>>> i = 0
>>> while i < len(a):
... if a[i] == s:
... # Processing for item found
... break
... i += 1
... else:
... # Processing for item not found
... print(s, 'not found in list.')
...
corge not found in list.
**注意:**上面显示的代码有助于说明这个概念,但是你实际上不太可能以这种方式搜索一个列表。
首先,列表通常用确定的迭代来处理,而不是一个while循环。明确迭代将在本系列的下一篇教程中介绍。
其次,Python 提供了在列表中搜索条目的内置方法。您可以使用in运算符:
>>> if s in a:
... print(s, 'found in list.')
... else:
... print(s, 'not found in list.')
...
corge not found in list.
list.index()方法也可以。如果在列表中找不到条目,这个方法会引发一个ValueError异常,所以您需要理解异常处理才能使用它。在 Python 中,使用try语句来处理异常。下面给出一个例子:
>>> try:
... print(a.index('corge'))
... except ValueError:
... print(s, 'not found in list.')
...
corge not found in list.
在本系列的后面,您将了解异常处理。
带有while循环的else子句有点奇怪,并不常见。但是,如果您发现有一种情况,您觉得它增加了代码的清晰度,请不要回避它!
无限循环
假设你写了一个理论上永远不会结束的while循环。听起来很奇怪,对吧?
考虑这个例子:
>>> while True:
... print('foo')
...
foo
foo
foo
.
.
.
foo
foo
foo
KeyboardInterrupt
Traceback (most recent call last):
File "<pyshell#2>", line 2, in <module>
print('foo')
该代码被 Ctrl + C 终止,从键盘产生一个中断。否则,事情会没完没了地继续下去。在所示的输出中,许多foo输出行已被删除并替换为垂直省略号。
显然,True永远不会是假的,否则我们都有大麻烦了。因此,while True:启动了一个无限循环,理论上将永远运行下去。
也许这听起来不像是您想要做的事情,但是这种模式实际上很常见。例如,您可能为一个服务编写代码,该服务启动并永远运行,接受服务请求。“永远”在这个上下文中的意思是直到你关闭它,或者直到宇宙的热寂,无论哪个先出现。
更通俗地说,记住循环可以用break语句来打破。基于循环体内识别的条件终止循环可能更简单,而不是基于在顶部评估的条件。
这是上面显示的循环的另一个变体,它使用.pop()从列表中连续删除项目,直到它为空:
>>> a = ['foo', 'bar', 'baz']
>>> while True:
... if not a:
... break
... print(a.pop(-1))
...
baz
bar
foo
当a变为空时,not a变为真,break语句退出循环。
您也可以在一个循环中指定多个break语句:
while True:
if <expr1>: # One condition for loop termination
break
...
if <expr2>: # Another termination condition
break
...
if <expr3>: # Yet another
break
在这种情况下,结束循环有多种原因,从几个不同的位置开始break通常更干净,而不是试图在循环头中指定所有的终止条件。
无限循环非常有用。请记住,您必须确保循环在某个点被打破,这样它才不会真正变成无限的。
嵌套的while循环
一般来说,Python 控制结构可以相互嵌套。例如,if / elif / else条件语句可以嵌套:
if age < 18:
if gender == 'M':
print('son')
else:
print('daughter')
elif age >= 18 and age < 65:
if gender == 'M':
print('father')
else:
print('mother')
else:
if gender == 'M':
print('grandfather')
else:
print('grandmother')
类似地,一个while循环可以包含在另一个while循环中,如下所示:
>>> a = ['foo', 'bar']
>>> while len(a): ... print(a.pop(0))
... b = ['baz', 'qux']
... while len(b): ... print('>', b.pop(0))
...
foo
> baz
> qux
bar
> baz
> qux
嵌套循环中的break或continue语句适用于最近的封闭循环:
while <expr1>:
statement
statement
while <expr2>:
statement
statement
break # Applies to while <expr2>: loop
break # Applies to while <expr1>: loop
此外,while循环可以嵌套在if / elif / else语句中,反之亦然:
if <expr>:
statement
while <expr>:
statement
statement
else:
while <expr>:
statement
statement
statement
while <expr>:
if <expr>:
statement
elif <expr>:
statement
else:
statement
if <expr>:
statement
事实上,所有 Python 控制结构可以根据您的需要任意混合。这是理所应当的。想象一下,如果有意想不到的限制,比如“一个while循环不能包含在一个if语句中”或者“while循环最多只能嵌套四层”,那会有多令人沮丧你很难把它们都记住。
看似任意的数字或逻辑限制被认为是糟糕的编程语言设计的标志。幸运的是,在 Python 中你不会发现很多。
单行while循环
与if语句一样,while循环可以在一行中指定。如果组成循环体的块中有多个语句,可以用分号(;)分隔:
>>> n = 5
>>> while n > 0: n -= 1; print(n)
4
3
2
1
0
不过这只适用于简单的语句。你不能将两个复合语句合并成一行。因此,您可以像上面一样在一行中指定一个while循环,并在一行中编写一个if语句:
>>> if True: print('foo')
foo
但是你不能这样做:
>>> while n > 0: n -= 1; if True: print('foo')
SyntaxError: invalid syntax
记住 PEP 8 不鼓励在一行中有多个语句。所以你可能不应该经常这样做。
结论
在本教程中,您学习了使用 Python while循环的无限迭代。您现在能够:
- 构建基本和复杂的
while循环 - 用
break和continue中断循环执行 - 使用带有
while循环的else子句 - 处理无限循环
现在,您应该已经很好地掌握了如何重复执行一段代码。
***参加测验:***通过我们的交互式“Python”while“Loops”测验来测试您的知识。完成后,您将收到一个分数,以便您可以跟踪一段时间内的学习进度:
*参加测验
本系列的下一篇教程将介绍带有for循环的确定迭代——循环执行,其中明确指定了重复的次数。
« Conditional Statements in PythonPython "while" LoopsPython "for" Loops »
立即观看**本教程有真实 Python 团队创建的相关视频课程。和书面教程一起看,加深理解: 掌握 While Loops******

