Python 的while
循环是在给定条件成立的情况下重复执行一段代码。与for
循环(迭代次数已知)不同,while
循环非常适合无法预先知道迭代次数的情况。
循环是 Python 中非常有用的构造,因此学习如何编写和使用循环对于 Python 开发人员来说是一项很棒的技能。
文本我们将一起学习:
while
是一个 Python 关键字,用于启动循环,只要条件为真,循环就会重复执行代码块。- 循环
while
的工作原理是在每次迭代开始时评估一个条件。如果条件为真,则循环执行。否则,循环终止。 while
当迭代次数未知时,循环很有用,例如等待条件改变或连续处理用户输入。while True
在 Python 中创建一个无限循环,该循环持续进行,直到break
出现语句或外部中断。- Python 缺少内置的 do-while 循环,但我们可以使用带有
break
条件终止语句的while True
循环来模拟它。
有了这些知识,我们就可以在 Python 程序中编写有效的while
循环,处理各种迭代需求。下面就和云朵君一起学习吧~点个推荐❤️支持一下!
Tip:本文为扫盲型推文,由浅入深,如果你不是初学者,可以跳过前部分的内容~
While 循环基本构造
在编程中,循环是一种控制流语句,你多次重复执行一组给定的操作。在实践中,你会发现两种主要的循环类型:
for
循环主要用于迭代已知次数,这在处理具有特定数量数据项的数据集合时很常见。while
循环通常用于迭代未知次数,当迭代次数取决于给定条件时很有用。
Python 中同时存在这两种循环,在本文中,云朵君和大家一起学习有关
while
循环的知识。在 Python 中,当你需要重复执行一系列任务(次数未知)时,通常会使用while
循环。
Pythonwhile
循环是包含语句头和代码块的复合语句,循环会一直运行,直到给定条件变为 false。while
循环的基本语法如下所示:
while condition:
在此语法中,condition
是一个表达式,循环将计算其真值。如果条件为真,则循环体运行。否则,循环终止。请注意,循环体可以由一个或多个必须正确缩进的语句组成。
以下是此语法的更详细分解:
condition
是用于定义退出条件的真实性评估的表达式。
下面是一个如何使用while
循环来迭代递减的数字序列的简单示例:
>>> number = 5
>>> while number > 0:
... print(number)
... number -= 1
...
5
4
3
2
1
在此示例中,number > 0
是循环条件。如果此条件返回 false 值,则循环终止。循环主体包含一个对 的调用,print()
该调用将值显示在屏幕上。接下来,减少number
的值。当循环在下一次迭代中评估条件时,此更改将产生不同的结果。
当条件保持为真时,循环运行。当条件变为假时,循环终止,程序继续执行循环体后的第一个语句。在此示例中,当number
达到小于或等于0
的值时,循环终止。
如果循环条件没有变为假,那么就可能进入无限循环。考虑以下循环,并将手指放在Ctrl+C
组合键附近以终止其执行:
>>> number = 5
>>> while number != 0:
... print(number)
... number -= 1
...
5
4
3
2
1
>>> number = 5
>>> while number != 0:
... print(number)
... number -= 2
...
5
3
1
-1
-3
-5
-7
-9
-11
Traceback (most recent call last):
...
KeyboardInterrupt
在此示例中,循环条件为number != 0
。当减少number
时,此条件成立。但是,如果将其减少 2,则条件可能永远不会为假,从而导致潜在的无限循环。在这种情况下,通常可以通过按
Ctrl + C
来终止循环,但这在大多数操作系统上会引发异常。
注意,while
循环在发生其他任何事情之前会先检查其条件。如果一开始就为假,那么循环体就永远不会运行:
>>> number = 0
>>> while number > 0:
... print(number)
... number -= 1
...
在这个例子中,当循环发现number
不大于时0
,它会立即终止执行,而不进入循环体。因此,循环体永远不会执行。
现在你已经了解了循环的基本语法while
,是时候深入研究 Python 中的一些实际示例了。在下一节中,你将看到如何将这些循环应用于实际场景。
while
循环高级语法
Pythonwhile
循环具有一些高级功能,使其灵活而强大。当你需要微调循环以满足特定的执行流程时,这些功能会很有帮助。
到目前为止,我们已经看到了每次迭代都运行整个循环体的示例。Python 提供了两个关键字来修改这种行为:
break
:立即终止循环。然后程序继续执行循环体后面的第一个语句。continue
:仅结束当前迭代。执行跳转回循环头,并评估循环条件以确定是否再次执行循环。
Python 的while
循环还具有其他语法。它们包含一个else
子句,当循环因条件成立而自然终止时,该子句会运行。在接下来的部分中,我们将进一步了解break
和
continue
语句的工作原理,以及如何在while
循环中有效地使用else
子句。
声明break
:提前退出循环
使用break
语句,我们可以终止while
循环的执行,并使程序继续执行循环体之后的第一个语句。
下面是一个简短的脚本,演示了break
语句的工作原理:
# break.py
number = 6
while number > 0:
number -= 1
if number == 2:
break
print(number)
print("Loop ended")
当
number
为2
时,到达break
语句,循环完全终止。程序执行跳转到脚本最后一行调用print()
。
从命令行运行break.py
会产生以下输出:
$ python break.py
5
4
3
Loop ended
循环正常打印值。当number
达到2
的值时,break
运行,终止循环并打印
Loop ended
到屏幕上。请注意,不会打印2
和1
。
需要注意的是,在条件语句break
之外使用语句几乎没有意义。假设你直接在循环体中包含一个break
语句,而没有将其包装在条件语句中。在这种情况下,循环将在第一次迭代中终止,可能无需运行整个循环体。
声明continue
:在迭代中跳过任务
接下来是continue
语句。使用此语句,我们可以在满足给定条件时跳过当前迭代中的某些任务。
下一个脚本与上一节中的脚本几乎相同,除了continue
代替的语句
break
:
# continue.py
number = 6
while number > 0:
number -= 1
if number == 2:
continue
print(number)
print("Loop ended")
输出continue.py
如下:
$ python continue.py
5
4
3
1
0
Loop ended
这次,当number
为时2
,该continue
语句终止该迭代。这就是为什么
2
不打印的原因。然后,控制权返回到循环头,在那里重新评估条件。循环继续,直到number
达到0
,此时它像之前一样终止。
条款else
:在自然循环终止时运行任务
Python 在while
循环末尾使用可选else
子句。语法如下所示:
while condition:
else:
仅当循环自然终止且未遇到任何语句时,else
子句下的代码才会运行。换句话说,只有在while
循环条件为false时,
break
才会执行。
请注意,在没有break
语句的循环中插入else
子句意义不大。在这种情况下,将else
代码块的内容放在循环之后(无需缩进)效果相同,而且更简洁。
while
循环中的else
子句什么时候有用?一个常见的用例else
是需要跳出循环。
# connection.py
import random
import time
MAX_RETRIES = 5
attempts = 0
while attempts < MAX_RETRIES:
attempts += 1
print(f"Attempt {attempts}: Connecting to the server...")
# Simulating a connection scenario
time.sleep(0.3)
if random.choice(False, False, False, True]):
print("Connection successful!")
break
print("Connection failed. Retrying...")
else:
print("All attempts failed. Unable to connect.")
此脚本模拟了连接到外部服务器的过程。循环中我们可以尝试连接一定次数,该次数由MAX_RETRIES
常量定义。如果连接成功,则break
语句终止循环。
注意:在上面的示例中,使用random
模块模拟了连接成功或失败的情况。在本文的其他几个示例中,我们还会用到这个模块。
当所有连接尝试失败时,else
子句将执行,告知我们所有尝试均未成功。请继续运行该脚本几次以检查结果。
有效的while循环
在 Python 中编写while
循环时,应确保其高效且可读性强。此外,还需要确保循环能够正确终止。
通常,当需要重复一系列操作直到给定条件变为假或保持为真时,会选择使用
while
循环。但当需要处理可迭代对象中的所有项时,这种循环并不适用。在这种情况下,我们应该使用循环for
。
在以下部分中,我们将学习如何有效地使用while
循环,避免无限循环,实现诸如break
和continue
之类的控制语句,以及利用else
子句优雅地处理循环完成。
根据while循环条件运行任务
while
循环的常见用例是等待资源可用后再继续使用。这在以下场景中很常见:
下面这个循环不断检查给定文件是否已创建:
# check_file.py
import time
from pathlib import Path
filename = Path("hello.txt")
print(f"Waiting for {filename.name} to be created...")
whilenot filename.exists():
print("File not found. Retrying in 1 second...")
time.sleep(1)
print(f"{filename} found! Proceeding with processing.")
with open(filename, mode="r") as file:
print("File contents:")
print(file.read())
此脚本中的循环对Path
对象使用了.exists()
方法。如果目标文件存在,则该方法返回True
。如果文件不存在,则not
运算符将检查结果取反并返回True
。如果文件不存在,则循环等待一秒钟,然后运行另一次迭代并再次检查该文件。
如果你运行这个脚本,那么你将得到如下结果:
$ python check_file.py
Waiting for hello.txt to be created...
File not found. Retrying in 1 second...
File not found. Retrying in 1 second...
File not found. Retrying in 1 second...
...
与此同时,我们可以打开另一个终端并创建该hello.txt
文件。当循环找到新创建的文件时,它将终止。然后,循环后的代码将运行,并将文件内容打印到屏幕上。
使用while
循环进行未知次数的迭代
你需要处理包含未知数量数据项的数据流时,while
循环也非常有用。在这种情况下,你不知道所需的迭代次数,因此可以使用包含控制条件True
的while
循环。这种技术提供了一种 Python 式的方法来编写运行未知次数迭代的循环。
为了说明这一点,假设我们需要读取一个持续提供数据的温度传感器。当温度等于或大于 28 摄氏度时,我们应该停止监控它。以下是完成此任务的循环:
# temperature.py
import random
import time
def read_temperature():
return random.uniform(20.0, 30.0)
whileTrue:
temperature = read_temperature()
print(f"Temperature: {temperature:.2f}°C")
if temperature >= 28:
print("Required temperature reached! Stopping monitoring.")
break
time.sleep(1)
在这个循环中,你使用True
作为循环条件,它会生成一个持续运行的循环。然后,你读取温度传感器并打印当前温度值。如果温度等于或大于 25 度,则跳出循环。否则,你等待一秒钟,然后再次读取传感器数据。
循环中从可迭代对象中删除元素
在迭代过程中修改集合可能会有风险,尤其是需要从目标集合中移除元素时。在某些情况下,使用while
循环可能是一个不错的解决方案。
例如,假设你需要处理一个值列表,并在处理完每个值后将其删除。在这种情况下,你可以使用如下while
循环:
>>> colors = "red", "blue", "yellow", "green"]
>>> while colors:
... color = colors.pop(
-1)
... print(f"Processing color: {color}")
...
Processing color: green
Processing color: yellow
Processing color: blue
Processing color: red
在布尔上下文中评估列表时,如果列表包含元素,则得到 True
;如果列表为空,则得到 False
。在此示例中,只要有元素,colorses
就为真。使用 .pop()
方法删除所有项目后,colors
就会变为 False
,循环也就结束了。
使用循环获取用户while
输入
从命令行获取用户输入是 Python
while
循环的常见用例。考虑以下使用内置函数input()
获取输入的循环。循环一直运行,直到我们输入单词"stop"
:
# user_input.py
line = input("Type some text: ")
while line != "stop":
print(line)
line = input("Type some text: ")
input()
函数要求用户输入一些文本。然后,将结果赋值给 line
变量。循环条件检查line
的内容是否与"stop"
不同,如果不同,则执行循环体。在循环内部,再次调用input()
。循环重复进行,直到用户输入单词
"stop"
。
此示例有效,但缺点是需要重复调用。我们可以使用海象运算符来避免重复调用input()
,如以下代码片段所示:
>>> while (line := input("Type some text: ")) != "stop":
... print(line)
...
Type some text: Python
Python
Type some text: Walrus
Walrus
Type some text: stop
在这个更新的循环中,你使用赋值表达式获取line
变量中的用户输入。同时,该表达式返回用户输入,以便将其与标记"stop"
值进行比较。
使用while
循环遍历迭代器
在使用迭代器和可迭代对象时,使用带有内置next()
函数的
while
循环可能是精细控制迭代过程的好方法。
为了让你理解它的工作原理,你需要用while
循环来重写一个for
循环。
# for_loop.py
requests = "first request", "second request", "third request"]
print("\nWith a for loop")
for request in requests:
print(f"Handling {request}")
print("\nWith a while loop")
it = iter(requests)
whileTrue:
try:
request = next(it)
except StopIteration:
break
print(f"Handling {request}")
这两个循环是等效的。运行脚本时,每个循环将依次处理三个请求:
$ python for_loop.py
With a for-loop
Handling first request
Handling second request
Handling third request
With a while-loop
Handling first request
Handling second request
Handling third request
Python 的 for
循环相当灵活和强大,如果需要遍历一个给定的集合,通常应该优先选择
for
而不是 while
。然而,将 for
循环转换成 while
循环(如上所示),可以让你在处理迭代器时更加灵活。
模拟 Do-While 循环
do-while
循环是一种控制流语句,无论循环条件是真还是假,它都会执行其代码块至少一次。
如果你之前用过C、C++、Java或JavaScript等语言,那么你可能会好奇 Python 的 do-while 循环在哪里。坏消息是 Python 没有这个循环。好消息是,你可以用一个带break
语句的while
循环来模拟它。
考虑以下示例,该示例在循环中接受用户输入:
>>> while True:
... number = int(input(
"Enter a positive number: "))
... print(number)
... if not number > 0:
... break
...
Enter a positive number: 1
1
Enter a positive number: 4
4
Enter a positive number: -1
-1
同样,此循环使用内置input()
函数接收用户输入。然后使用 将输入转换为整数int()
。如果用户输入的数字小于0
或等于,则break
语句运行,循环终止。
请注意,为了在 Python 中模拟 do-while 循环,终止循环的条件位于循环末尾,并且其循环体是一个break
语句。还需要强调的是,在这种类型的循环中,循环体至少运行一次。
使用while
循环进行事件循环
Python 中while
循环的另一个常见且扩展的用例是创建事件循环,事件循环是等待某些特定操作(称为事件)的无限循环。一旦事件发生,循环就会将其分派给相应的事件处理程序#Event_handler)。
以下是一些可以找到事件循环的经典字段示例:
例如,假设你想实现一个猜数字的游戏。你可以用一个while
循环来实现:
# guess.py
from random import randint
LOW, HIGH = 1, 10
secret_number = randint(LOW, HIGH)
clue = ""
# Game loop
whileTrue:
guess = input(f"Guess a number between {LOW} and {HIGH} {clue} ")
number = int(guess)
if number > secret_number:
clue = f"(less than {number})"
elif number < secret_number:
clue = f"(greater than {number})"
else:
break
print(f"You guessed it! The secret number is {number}")
在此示例中,游戏循环运行游戏逻辑。首先,它使用input()
接收用户的猜测,将其转换为整数,并检查它是大于还是小于秘密数字。当用户的猜测等于秘密数字时,执行该子句else
。在这种情况下,循环中断,游戏显示获胜消息。
探索无限while
循环
有时,你可能会编写一个无法自然终止的while
循环。这种循环通常被称为无限循环,尽管这个名称并不十分准确,因为最终你还是需要以某种方式终止循环。
你可能有意或无意地编写了一个无限循环。有意的无限循环是强大的工具,通常用于需要持续运行直至满足外部条件的程序中,例如游戏循环、服务器进程以及事件驱动的应用程序(例如 GUI 应用程序或异步代码)。
相反,无意的无限while
循环通常是由于某种逻辑问题导致循环条件永远无法成立。例如,以下循环可能会发生这种情况:
在这些情况下,循环会错误地继续运行,直到被外部终止。
在接下来的章节中,你将了解这两种类型的无限循环,以及如何在代码中处理它们。首先,你将从无意的无限循环开始。
无意的无限循环
假设你编写了一个由于内部错误而永不结束的while
循环。回到本文第一部分的示例,你有一个持续运行的循环:
>>> number = 5
>>>
while number != 0:
... print(number)
... number -= 2
...
5
3
1
-1
-3
-5
-7
-9
-11
Traceback (most recent call last):
...
KeyboardInterrupt
要终止此代码,我们必须按下Ctrl+C,这会通过键盘中断程序的执行。否则,循环将无限期运行,因为其条件永远不会变为 false。在实际代码中,我们通常需要设置适当的循环条件,以防止意外的无限执行。
在大多数情况下,我们可以通过修复条件本身或内部循环逻辑来防止潜在的无限循环,以确保条件在循环执行的某个时刻变为假。
在上面的例子中,我们可以稍微修改一下条件来解决这个问题:
>>> number = 5
>>> while number > 0:
... print(number)
... number -= 2
...
...
5
3
1
这次,循环不再向下移动值,而是在number
值等于或小于0
时终止。
或者,我们可以在循环体中使用附加条件来break
终止循环:
>>> number = 5
>>> while number != 0:
... if number <= 0:
... break
... print(number)
... number -= 2
...
5
3
1
这个循环与原始循环条件相同。但是,它在循环体中包含了一个故障安全条件,以便在主条件失败时终止循环。
如何修复无意中引发的无限循环,很大程度上取决于循环条件和循环主体中使用的逻辑。因此,你应该仔细分析每种情况,以确定正确的解决方案。
有意无限循环
有意无限while
循环非常常见且有用。然而,正确编写它们需要确保适当的退出条件,避免性能问题,并防止意外的无限执行。
例如,你可能想编写一个服务代码,让它启动并永久运行,接受服务请求。在这种情况下, “永久”指的是直到你关闭它为止。
编写无限循环的典型方法是使用while True
构造。为了确保循环自然终止,你应该添加一个或多个break
包含在适当条件中的语句:
while True:
if condition_1:
break
...
if condition_2:
break
...
if condition_n:
break
当你有多个理由结束循环时,这种语法很有效。通常,从几个不同的位置跳出循环比在循环头中指定所有终止条件更简洁。
为了在实践中看到这种构造,请考虑以下要求用户提供密码的无限循环:
# password.py
MAX_ATTEMPTS = 3
correct_password = "secret123"
attempts = 0
whileTrue:
password = input("Password: ").strip()
attempts += 1
if password == correct_password:
print("Login successful! Welcome!")
break
if attempts >= MAX_ATTEMPTS:
print("Too many failed attempts.")
break
else:
print(f"Incorrect password. {MAX_ATTEMPTS - attempts} attempts left.")
此循环有两个退出条件。第一个条件检查密码是否正确。第二个条件检查用户是否已达到输入正确密码的最大尝试次数。这两个条件都包含一个break
语句,用于正常结束循环。
结论
至此,大家和云朵君已经学习了很多关于 Pythonwhile
循环的知识,它是迭代过程中至关重要的控制流结构。你学习了如何使用while
循环重复执行任务直到满足条件,如何使用break
和continue
语句调整循环,以及如何防止或编写无限循环。
理解
while
循环对于 Python 开发人员来说至关重要,因为它们可以让我们处理需要根据条件重复执行的任务。