Py学习  »  Python

彻底悟了!Python 循环

数据STUDIO • 2 月前 • 157 次点击  


Python 的while循环是在给定条件成立的情况下重复执行一段代码。与for循环(迭代次数已知)不同,while循环非常适合无法预先知道迭代次数的情况。

循环是 Python 中非常有用的构造,因此学习如何编写和使用循环对于 Python 开发人员来说是一项很棒的技能。

文本我们将一起学习:

  • while是一个 Python 关键字,用于启动循环,只要条件为真,循环就会重复执行代码块。
  • 循环 while的工作原理是在每次迭代开始时评估一个条件。如果条件为真,则循环执行。否则,循环终止。
  • while当迭代次数未知时,循环很有用,例如等待条件改变或连续处理用户输入。
  • while True在 Python 中创建一个无限循环,该循环持续进行,直到break出现语句或外部中断。
  • Python 缺少内置的 do-while 循环,但我们可以使用带break 条件终止语句的while True循环来模拟它。

有了这些知识,我们就可以在 Python 程序中编写有效的while循环,处理各种迭代需求。下面就和云朵君一起学习吧~点个推荐❤️支持一下!

Tip:本文为扫盲型推文,由浅入深,如果你不是初学者,可以跳过前部分的内容~

While 循环基本构造

在编程中,循环是一种控制流语句,你多次重复执行一组给定的操作。在实践中,你会发现两种主要的循环类型:

  1. for循环主要用于迭代已知次数,这在处理具有特定数量数据项的数据集合时很常见。
  2. while循环通常用于迭代未知次数,当迭代次数取决于给定条件时很有用。

Python 中同时存在这两种循环,在本文中,云朵君和大家一起学习有关 while循环的知识。在 Python 中,当你需要重复执行一系列任务(次数未知)时,通常会使用while循环。

Pythonwhile循环是包含语句头代码块的复合语句,循环会一直运行,直到给定条件变为 false。while循环的基本语法如下所示:

while condition:
   

在此语法中,condition是一个表达式,循环将计算其真值。如果条件为真,则循环体运行。否则,循环终止。请注意,循环体可以由一个或多个必须正确缩进的语句组成。

以下是此语法的更详细分解:

  • while是启动循环头的关键字。
  • 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到屏幕上。请注意,不会打印21

需要注意的是,在条件语句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循环,避免无限循环,实现诸如breakcontinue之类的控制语句,以及利用else子句优雅地处理循环完成。

根据while循环条件运行任务

while循环的常见用例是等待资源可用后再继续使用。这在以下场景中很常见:

  • 等待文件创建或填充
  • 检查服务器是否在线
  • 轮询数据库直到记录准备好
  • 在发出请求之前确保REST API具有响应能力

下面这个循环不断检查给定文件是否已创建:

# 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循环也非常有用。在这种情况下,你不知道所需的迭代次数,因此可以使用包含控制条件Truewhile循环。这种技术提供了一种 Python 式的方法来编写运行未知次数迭代的循环。

为了说明这一点,假设我们需要读取一个持续提供数据的温度传感器。当温度等于或大于 28 摄氏度时,我们应该停止监控它。以下是完成此任务的循环:

# temperature.py
import random
import time

def read_temperature():
    return random.uniform(20.030.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)。

以下是一些可以找到事件循环的经典字段示例:

  • 图形用户界面(GUI)框架
  • 游戏开发
  • 异步应用程序
  • 服务器进程

例如,假设你想实现一个猜数字的游戏。你可以用一个while循环来实现:

# guess.py
from random import randint

LOW, HIGH = 110

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循环重复执行任务直到满足条件,如何使用breakcontinue语句调整循环,以及如何防止或编写无限循环。

理解 while循环对于 Python 开发人员来说至关重要,因为它们可以让我们处理需要根据条件重复执行的任务。


🏴‍☠️宝藏级🏴‍☠️ 原创公众号『数据STUDIO』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括可戳👉 PythonMySQL数据分析数据可视化机器学习与数据挖掘爬虫 等,从入门到进阶!

长按👇关注- 数据STUDIO -设为星标,干货速递

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/181907
 
157 次点击