如果你是从C、C++、Java或JavaScript这样的语言来到Python的,那么你可能会错过他们的do-while循环结构。do-while 循环是一个常见的控制流语句,无论循环条件是真还是假,都至少执行一次其代码块。这种行为依赖于这样一个事实,即循环条件在每次迭代结束时被评估。所以,第一个迭代总是运行的。
这种类型的循环最常见的用例之一是接受和处理用户的输入。考虑一下下面这个用C语言编写的例子。
#include <stdio.h>
int main() {
int number;
do {
printf("Enter a positive number: ");
scanf("%d", &number);
printf("%d\n", number);
} while (number > 0);
return 0;
}
这个小程序运行一个do...while 循环,要求用户输入一个正数。然后,输入的数据被存储在number ,并打印到屏幕上。该循环一直运行这些操作,直到用户输入一个非正数。
如果你编译并运行这个程序,那么你会得到以下行为。
Enter a positive number: 1
1
Enter a positive number: 4
4
Enter a positive number: -1
-1
循环条件,number > 0 ,在循环结束时被评估,这保证了循环主体至少运行一次。这个特点使do-while循环与普通的while循环不同,后者在开始时就评估循环条件。在while循环中,不能保证循环主体的运行。如果循环条件从一开始就是假的,那么主体就根本不会运行。
注意:在本教程中,你将把控制while或do-while循环的条件称为循环条件。这个概念不应该与循环的主体相混淆,在C语言中,主体是夹在大括号中的代码块,在Python中则是缩进的。
拥有do-while循环结构的一个原因是效率。例如,如果循环条件意味着昂贵的操作,并且循环必须运行n次*(n≥1),那么该条件将在do-while循环中运行n次。与此相反,一个普通的while循环将运行昂贵的条件n*+ 1次。
Python 没有一个 do-while 循环结构。为什么呢?很明显,核心开发者从来没有为这种类型的循环找到一个好的语法。也许,这就是Guido van Rossum 拒绝PEP315 的原因,它试图在语言中加入 do-while 循环。一些核心开发人员希望有一个do-while循环,并希望围绕这个话题重新进行讨论。
同时,你将探索Python中可用的替代方案。简而言之,**如何在 Python 中模拟 do-while 循环?**在本教程中,你将学习如何用while ,创建行为类似于do-while循环的循环。
免费下载。 获得Python技巧中的一个样本章节。这本书通过简单的例子向你展示了Python的最佳实践,你可以立即应用这些例子来编写更漂亮的+Pythonic代码。
简而言之:使用while 循环和break 语句
在Python中模拟Do-While循环的最常见的技术是使用一个无限的while 循环,其中有一个break语句包裹在一个if 语句中,该语句检查一个给定的条件,如果该条件为真则中断迭代。
while True:
# Do some processing...
# Update the condition...
if condition:
break
这个循环使用True 作为其形式条件。这个技巧把循环变成了一个无限的循环。在条件语句之前,循环运行所有需要的处理,并更新破缺条件。如果这个条件评估为真,那么break 语句就脱离了循环,程序执行继续其正常路径。
注意:使用一个无限循环和一个break 语句可以模拟 do-while 循环。这种技术是Python社区普遍推荐的,但它并不完全安全。
例如,如果你在break 语句之前引入一个continue 语句,那么这个循环就会错过中断条件,并运行到一个不受控制的无限循环。
下面是如何编写相当于你在本教程的介绍中所写的C程序的Python。
>>>
>>> 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 语句就会运行,循环就会终止。
有时,你会遇到这样的情况:你需要保证一个循环至少运行一次。在这些情况下,你可以像上面那样使用while 和break 。在下一节中,你将编写一个猜数字的游戏,使用这样一个do-while循环来接受和处理用户在命令行的输入。
Do-While 循环在实践中是如何工作的?
Do-while 循环最常见的使用情况是接受和处理用户的输入。作为一个实际的例子,假设你有一个用JavaScript实现的数字猜测游戏。该代码使用一个do...while 循环来处理用户的输入。
1// guess.js
2
3const LOW = 1;
4const HIGH = 10;
5
6let secretNumber = Math.floor(Math.random() * HIGH) + LOW;
7let clue = '';
8let number = null;
9
10do {
11 let guess = prompt(`Guess a number between ${LOW} and ${HIGH} ${clue}`);
12 number = parseInt(guess);
13 if (number > secretNumber) {
14 clue = `(less than ${number})`;
15 } else if (number < secretNumber) {
16 clue = `(greater than ${number})`;
17 }
18} while (number != secretNumber);
19
20alert(`You guessed it! The secret number is ${number}`);
这个脚本做了几件事。下面是对所发生的事情的分解。
-
第3行和第4行定义了两个常数,以划定秘密数字所处的间隔时间。
-
第6行到第8行定义了一些变量,用来存储秘密号码、线索信息和
number的初始值,它将保存用户的输入。 -
第10行开始一个
do...while循环,以处理用户的输入并确定用户是否猜出了秘密号码。 -
第11行定义了一个局部变量,
guess,用来存储用户在命令行提供的输入。 -
第12行使用
parseInt(),将输入值转换为一个整数。 -
第13行定义了一个条件语句,检查输入的数字是否大于秘密数字。如果是这样,那么
clue被设置为一个适当的信息。 -
第15行检查输入的数字是否小于秘密数字,然后相应地设置
clue。 -
第18行定义了循环条件,以检查输入数字是否与秘密数字不同。在这个具体的例子中,循环将继续运行,直到用户猜出秘密号码。
-
第20行最后启动了一个提示框,通知用户猜测成功。
现在,假设你想把上述例子翻译成Python代码。一个在Python中的等效数字猜测游戏将看起来像这样。
# guess.py
from random import randint
LOW, HIGH = 1, 10
secret_number = randint(LOW, HIGH)
clue = ""
while True:
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}")
这段Python代码的工作原理就像它的等效JavaScript代码一样。主要的区别是,在这种情况下,你使用的是一个普通的while 循环,因为Python没有do...while 循环。在这个Python的实现中,当用户猜出秘密数字时,else 子句就会运行,打破循环。最后一行代码打印出猜测成功的信息。
像你在上面的例子中那样使用一个无限循环和一个break 语句,是在Python中模拟do-while循环的最广泛使用的方法。
Do-While 和 While 循环之间的区别是什么?
简而言之,do-while 循环和 while 循环的主要区别是,前者至少执行一次其主体,因为循环条件在最后被检查。另一方面,如果条件评估为 "真",常规的while循环的主体就会执行,这是在循环的开始阶段进行测试。
下面的表格总结了这两种类型的循环之间的主要区别。
| while | do-while |
|---|---|
| 是一个入口控制的循环 | 是一个出口控制的循环 |
| 只在循环条件为真时运行 | 运行直到循环条件为假 |
| 首先检查条件,然后执行循环的主体 | 先执行循环的主体,然后再检查条件 |
| 如果循环条件最初是假的,则零次执行循环的主体 | 无论循环条件的真值如何,至少执行一次循环的主体 |
| 在n次迭代中检查循环条件n+1次 | 检查循环条件n次,n是迭代的次数 |
while循环是一种控制流结构,它提供了一个通用的、多功能的循环。它允许你在一个给定的条件保持为真时重复运行一组语句。do-while 循环的使用情况更为具体。它主要用于这样的情况:只有当循环的主体至少已经运行过一次时,检查循环条件才有意义。
你可以用什么方法来模拟 Python 中的 Do-While 循环?
在这一点上,你已经学会了在 Python 中模拟 do-while 循环的推荐或最常见的方法。然而,在模拟这种类型的循环时,Python 是相当灵活的。一些程序员总是使用无限while 循环和break 语句。其他程序员使用他们自己的公式。
在本节中,你将通过一些替代技术来模拟 do-while 循环。第一种方法是在循环开始前运行你的第一个操作。第二种方法是指在循环开始前使用一个最初被设置为真值的循环条件。
在循环之前进行第一个操作
正如你已经学过的,do-while循环最相关的特征是,循环的主体总是至少运行一次。为了使用while 循环来模拟这个功能,你可以在循环开始之前,取循环的主体并运行它。然后你可以在循环内重复运行主体。
这个方案听起来很重复,如果你不使用某种技巧的话,就会很重复。幸运的是,你可以使用一个函数来包装循环的主体,防止重复。使用这种技术,你的代码将看起来像这样。
condition = do_something()
while condition:
condition = do_something()
对do_something() 的第一次调用保证了所需功能至少运行一次。循环内对do_something() 的调用只在condition 为真时运行。请注意,你需要在每次迭代中更新循环条件,以使这种模式正确工作。
下面的代码显示了你如何使用这种技术来实现你的数字猜谜游戏。
# guess.py
from random import randint
LOW, HIGH = 1, 10
secret_number = randint(LOW, HIGH)
clue = ""
def process_move(clue):
user_input = input(f"Guess a number between {LOW} and {HIGH} {clue} ")
number = int(user_input)
if number > secret_number:
clue = f"(less than {number})"
elif number < secret_number:
clue = f"(greater than {number})"
return number, clue
number, clue = process_move(clue) # First iteration
while number != secret_number:
number, clue = process_move(clue)
print(f"You guessed it! The secret number is {number}")
在这个新版本的猜数字游戏中,你将所有的循环功能打包到process_move() 。这个函数返回当前的数字,你将在以后检查循环条件时使用它。它还会返回线索信息。
请注意,process_move() 在循环开始前运行一次,模仿了do-while循环的主要特征,即至少运行一次其主体。
在循环内部,你调用该函数来运行游戏的主要功能,并相应地更新循环条件。
使用一个初始为真的循环条件
使用一个最初设置为True 的循环条件是模仿do-while循环的另一个选择。在这种情况下,你只需要在循环开始运行之前将循环条件设置为True 。这种做法可以确保循环的主体至少运行一次。
do = True
while do:
do_something()
if condition:
do = False
这种替代结构与你在上一节中使用的结构非常相似。主要区别在于,循环条件是一个布尔变量,在循环中被更新。
这种技术也类似于使用无限while 循环和break 语句的技术。然而,这个更明确,更易读,因为它让你使用描述性的变量名,而不是像break 语句和一个硬编码的条件True 。
**注意:**有时为布尔变量命名是比较自然的,这样你把它设置为True ,以便跳出循环。在这些情况下,你可以用类似while not done: 的东西开始循环,并在循环内将done 设置为True 。
你可以使用这种技术来重写你的数字猜测游戏,就像下面的代码例子一样。
# guess.py
from random import randint
LOW, HIGH = 1, 10
secret_number = randint(LOW, HIGH)
clue = ""
number_guessed = False
while not number_guessed:
user_input = input(f"Guess a number between {LOW} and {HIGH} {clue} ")
number = int(user_input)
if number > secret_number:
clue = f"(less than {number})"
elif number < secret_number:
clue = f"(greater than {number})"
else:
number_guessed = True
print(f"You guessed it! The secret number is {number}")
在这个例子中,你首先定义了一个布尔变量,number_guessed ,它允许你控制循环。在这个循环中,你像往常一样处理用户的输入。如果用户猜中了秘密数字,那么number_guessed 被设置为True ,程序就会跳出循环执行。
总结
在本教程中,你已经学会了在 Python 中模拟一个 do-while 循环。该语言没有这种循环结构,你可以在 C、C++、Java 和 JavaScript 等语言中找到。你学到了你总是可以在常规的 while 循环的帮助下写一个 do-while 循环,而且你可以使用几种不同的模式之一来完成它。
模仿do-while循环的最常见的技术是创建一个无限的while 循环,在循环体的末端有一个条件语句。这个条件控制循环,并使用 break语句跳出循环。
你还学会了如何使用一些替代技术来提供与do-while循环相同的功能。你的选择包括在循环之前进行第一组操作,或者使用一个最初设置为True 的布尔变量来控制循环。
有了这些知识,你就可以开始在你自己的Python代码中模拟do-while循环了。
🐍 Python 技巧 💌
每隔几天就会有一个短小精悍的Python技巧送到你的收件箱中。从来没有垃圾邮件。任何时候都可以取消订阅。由Real Python团队策划。