控制流 {#control-flow}

截止到现在,在我们所看过的程序中,总是有一系列语句从上到下精确排列,并交由 Python 忠实地执行。如果你想改变这一工作流程,应该怎么做?就像这样的情况:你需要程序作出一些决定,并依据不同的情况去完成不同的事情,例如依据每天时间的不同打印出 ‘早上好’ ‘Good Morning’ 或 ‘晚上好’ ‘Good Evening’?

正如你可能已经猜测到的那番,这是通过控制流语句来实现的。在 Python 中有三种控制流语句——if forwhile

if 语句

if 语句用以检查条件:如果 条件为真(True),我们将运行一块语句(称作 if-blockif 块),否则 我们将运行另一块语句(称作 else-blockelse 块)。其中 else 从句是可选的。

案例(保存为 if.py):

  1. {% include "./programs/if.py" %}

输出:

  1. {% include "./programs/if.txt" %}

它是如何工作的

在这个程序中,我们根据用户猜测的数字来检查这一数字是否是我们所设置的。我们将变量 number 设为任何我们所希望的整数,例如 23。然后,我们通过 input() 函数来获取用户的猜测数。所谓函数是一种可重复使用的程序。我们将在下一章详细讨论它。

我们为内置的 input 函数提供一串打印到屏幕上的字符串并等待用户的输入。一旦我们输入了某些内容并按下键盘上的 enter 键,input() 函数将以字符串的形式返回我们所输入的内容。然后我们通过 int 将这个字符串转换成一个整数并将其储存在变量 guess 中。实际上,int 是一个类(Class),但你现在你所需要知道的就是你可以使用它将一串字符串转换成一个整数(假设这个字符串的文本中含有一个有效的整数)。

接下来,我们将用户提供的猜测数与我们所选择的数字进行对比。如果它们相等,我们就打印一条成功信息。在这里要注意到我们使用缩进级别来告诉 Python 哪些语句分别属于哪个块。这便是为什么在 Python 中缩进如此重要。我希望你能够坚持“缩进一致”的原则,你能做到吧?

另外需要注意的是 if 语句在结尾处包含一个冒号——我们借此向 Python 指定接下来会有一块语句在后头。

然后,我们检查猜测数是否小于我们选择的数字,如果是,我们将告诉用户他们必须猜一个更高一些的数字。在这里我们使用的是 elif 语句,它们实际上将两个相连的 if else-if else 语句合并成一句 if-elif-else 语句。这能够使程序更加简便,并且可以减少所需要的缩进量。

elifelse 同样都必须有一个冒号在其逻辑行的末尾,后面跟着与它们相应的语句块(当然,别忘了恰当的缩进)。

你可以在 if 块的 一个 if 语句中设置另一个 if 语句,并可以如此进行下去——这被称作嵌套的 if 语句。

要记住 elifelse 部分都是可选的。一个最小规模且有效的 if 语句是这样的:

  1. if True:
  2. print('Yes, it is true')

当 Python 完整执行了 if 语句及与其相关的 elifelse 子句后,它将会移动至包含 if 语句的代码块的下一句语句中。在本例中,也就是主代码块(程序开始执行的地方),其下一句语句就是 print('Done') 语句。在完成这些工作后,Python 会发现已行至程序末尾并宣告工作的完成。

尽管这是一个非常简单的程序,我也一直在其中指出你应该注意的事情。所有的这些都可算是简单易懂(对于那些具有 C/C++ 背景的人来说是相当简单易懂)。不过在开始时它们还是可能会不断吸引你的注意,不断地去在意它们。但经过一些更丰富的操作后你就会习惯它们及其中的逻辑,它们对于你来说将会成为“自然而然”的事情。

针对 C/C++ 程序员的提示

Python 中不存在 switch 语句。你可以通过使用 if..elif..else 语句来实现同样的事情(在某些情况下,使用一部字典能够更快速地完成)。

while 语句

while 语句能够让你在条件为真的前提下重复执行某块语句。 while 语句是 循环(Looping) 语句的一种。while 语句同样可以拥有 else 子句作为可选选项。

案例(保存为 while.py):

  1. {% include "./programs/while.py" %}

输出:

  1. {% include "./programs/while.txt" %}

它是如何工作的

在这一程序中,我们依旧通过猜数游戏来演示,不过新程序的优点在于能够允许用户持续猜测直至他猜中为止——而无需像我们在上一节中所做的那样,每次猜测都要重新运行程序。这种变化恰到好处地演示了 while 语句的作用。

首先我们将 inputif 语句移到 while 循环之中,并在 while 循环开始前将变量 running 设置为 True。程序开始时,我们首先检查变量 running 是否为 True,之后再执行相应的 while 块。在这一代码块被执行之后,将会重新对条件进行检查,在本例中也就是 running 变量。如果它依旧为 True,我们将再次执行 while 块,否则我们将继续执行可选的 else 块,然后进入到下一个语句中。

else 代码块在 while 循环的条件变为 False 时开始执行——这个开始的时机甚至可能是在第一次检查条件的时候。如果 while 循环中存在一个 else 代码块,它将总是被执行,除非你通过 break 语句来中断这一循环。

TrueFalse 被称作布尔(Boolean)型,你可以将它们分别等价地视为 10

针对 C/C++ 程序员的提示

你可以在 while 循环中使用 else 从句。

for 循环

for...in 语句是另一种循环语句,其特点是会在一系列对象上进行迭代(Iterates),意即它会遍历序列中的每一个项目。我们将在后面的序列(Sequences)章节中了解有关它的更多内容。现在你所需要的就是所谓队列就是一系列项目的有序集合。

案例(保存为 for.py):

  1. {% include "./programs/for.py" %}

输出:

  1. {% include "./programs/for.txt" %}

它是如何工作的

在这一程序中,我们打印了一个数字序列。我们通过内置的 range 函数生成这一数字序列。

在这里我们所要做的事情是提供两个数字,而 range 将会返回一个数字序列,从第一个数字开始,至第二个数字结束。举个例子,range(1,5) 将输出序列 [1, 2, 3, 4]。在默认情况下,range 将会以 1 逐步递增。如果我们向 range 提供第三个数字,则这个数字将成为逐步递增的加数。同样举个例子来说明,range(1,5,2) 将会输出 [1, 3]。要记住这一序列扩展直到第二个数字,也就是说,它不会包括第二个数字在内。

另外需要注意的是,range() 每次只会生成一个数字,如果你希望获得完整的数字列表,要在使用 range() 时调用 list()。例如下面这样:list(range(5)) ,它将会返回 [0, 1, 2, 3, 4]。有关列表的详细解释将会在 《数据结构》一章呈现。

然后 for 循环就会在这一范围内展开递归——for i in range(1,5) 等价于 for i in [1, 2, 3, 4],这个操作将依次将队列里的每个数字(或是对象)分配给 i,一次一个,然后以每个 i 的值执行语句块。在本例中,我们这一语句块所做的就是打印出这些值。

同样要记住,else 部分是可选的。当循环中包含他时,它总会在 for 循环结束后开始执行,除非程序遇到了 break 语句。

另一个需要注意的地方是 for...in 能在任何队列中工作。在这里,我们有的是通过内置的 range 函数生成的一串数字列表,但总体来说我们可以包含任何类型对象的队列!我们将会在后面的章节详细解释这一观念。

针对 C/C++/Java/C# 程序员的提示

Python 中的 for 循环和 C/C++ 中的 for 循环可以说是完全不同。C# 程序员会注意到 Python 中的 for 循环与 C# 中的 foreach 循环相似。Java 程序员则会注意到它同样与 Java 1.5 中的 for (int i : IntArray) 无甚区别。

在 C/C++ 中,如果你希望编写 for (int i = 0; i < 5; i++),那么在 Python 你只需要写下 for i in range(0,5)。正如你所看到的,Python 中的 for 循环将更加简单,更具表现力且更不容易出错。

break 语句 {#break-statement}

break 语句用以中断(Break)循环语句,也就是中止循环语句的执行,即使循环条件没有变更为 False,或队列中的项目尚未完全迭代依旧如此。

有一点需要尤其注意,如果你 中断 了一个 forwhile 循环,任何相应循环中的 else 块都将不会被执行。

案例(保存为 break.py):

  1. {% include "./programs/break.py" %}

输出:

  1. {% include "./programs/break.txt" %}

它是如何工作的

在本程序中,我们重复地接受用户的输入内容并打印出每一次输入内容的长度。我们通过检查用户输入的是否是 quit 这一特殊条件来判断是否应该终止程序。我们通过中断循环并转进至程序末尾来结束这一程序。

输入字符串的长度可以通过内置的 len 函数来找到。

记住,break 语句同样可以适用于 for 循环。

Swaroop 的诗意 Python

我所使用的输入内容是一首我所写的小诗:

  1. Programming is fun
  2. When the work is done
  3. if you wanna make your work also fun:
  4. use Python!

continue 语句 {#continue-statement}

continue 语句用以告诉 Python 跳过当前循环块中的剩余语句,并继续该循环的下一次迭代。

案例(保存为 continue.py):

  1. {% include "./programs/continue.py" %}

输出:

  1. {% include "./programs/continue.txt" %}

它是如何工作的

在本程序中,我们接受来自用户的输入内容,但是只有在输入的字符串其长至少 3 字符我们才会对其进行处理。为此,我们使用内置的 len 函数和来获取字符串的长度,如果其长度小于 3,我们便通过使用 continue 语句跳过代码块中的其余语句。否则,循环中的剩余语句将被执行,并在此处进行我们所希望的任何类型的处理。

要注意 continue 语句同样能用于 for 循环。

总结

我们已经了解了三种控制流语句——ifwhilefor ——及其相关的 breakcontinue 语句是如何工作的。这些语句是 Python 中一些最常用的部分,因此,习惯去使用它们是必要的。

接下来,我们将了解如何创建并使用函数。