# 控制流

带目前为止,我们看到的程序都是自上而下顺序执行的。如果你想改变它的执行顺序,该怎样做呢?例如,你想让程序作出根据不同的情况采取不同的措施。例如,根据一天的时间不同,打印`早上好`或`晚上好`。

你可能已经猜到了,这要通过使用控制流语句。在Python中有三个控制流语句-- `if`, `for` 和 `while`。

## if 语句

`if`语句是用来检查一个条件:**如果**条件为真,我们就运行一个代码块(你为**if代码块**),**否则**我们执行另一个代码块(称为**else代码块**)。**else子句**是可选的。

例如 (保存为 `if.py`):

```python
number = 23
guess = int(input('请输入一个整数: '))
if guess == number:
# 新块从这里开始
print('恭喜,你猜对了。')
print('(但你没有获得任何奖品!)')
# 新块在这里结束
elif guess < number:
# 另一个块
print('不对,你猜的有点儿小')
# 在一个块中你可以做你想做的任何事...
else:
print('不对,你猜的有点大')
# 你猜的数比number大时才能到这里
print('完成')
# if语句执行完后,最后的语句总是被执行
```

输出:

```shell

C:\> python if.py

请输入一个整数: 50

不对,你猜的有点儿大

完成

C:\> python if.py

请输入一个整数: 22

不对,你猜的有点儿小

完成

C:\> python if.py

请输入一个整数: 23

恭喜,你猜对了。

(但你没有获得任何奖品!)

完成

```

**它是如何工作的:**

在这个程序中,用户输入了一个猜测的数字,我们的程序检查它是否等于我们预先指定的数字。我们给变量`number`设置我们想要的任何整数,比如`23`。然后,我们使用`input()` 函数获取用户的输入。函数是可重用的代码块,我们在[下一章](function.md)中会了解关于它们的更多信息。

我们给内置的`input`函数提供一个字符串,该函数将其打印到屏幕上并等待用户输入。一旦我们输入一些内容并按下回车键,`input()`函数把我们的输入作为一个字符串返回。然后,我们使用`int`将这个字符串转换为整数,并将其存储在变量`guess`中。实际上,`int` 是一个类,但现在你仅需要知道可以使用它来将一个字符串转变为一个整数(假设文本中的字符串包含一个有效的整数)。

接下来,我们比较用户猜的数和我们选择的数。如果他们相等,我们打印一条成功的消息。注意,我们使用缩进级别告诉Python哪个语句属于哪个代码块。这就是为什么缩进在ython中是如此重要。我希望你坚持"一致的缩进"的规则,好吗?

注意,`if`语句在最后有一个冒号——我们告诉Python:下一行要开始一个代码块。

然后,我们检查猜的数是否小于这个数字,如果是,我们通知用户,他们猜的数必须比那个数稍高。我们这里使用的是`elif`子句,实际上将两个相关的 `if else-if else`语句组合为一个语句`if-elif-else`,这使程序更简单且减少所缩进的数量。

`elif`和`else`语句也必须在逻辑行结束时有一个冒号,后跟相应的代码块(当然要通过适当的缩进)

你可以在`if`语句的if块中有另一个`if`语句——这称为`if`语句嵌套。

记住,`elif` 和`else`部分是可选的。一个最小的有效的`if`语句是:

```python
if True:
print('是的,它为真')
```

在Python执行完成完整的if语句以及相关的`elif`和`else`子句,它移动到`if`包含语句的代码块中下一个语句。在本例中,它是主代码块(程序开始执行的地方),接下来的语句是 `print('完成')`。在这之后,Python将看到程序的结尾,并完成它。

尽管这是一个非常简单的程序,但是它麻雀虽小五脏俱全。Python的语法简单而且直接(对那些有C/C++背景的人是惊人的简单)。刚一开始的时候你可能还需要注意一下Python的语法要求,但经过一段时间的练习,你会感到非常舒服,有着“自然”的感觉。

> **C/C++程序员需要注意**

> 在Python中没有`switch`语句。您可以使用一个`if..elif..else`语句做同样的事(和在某些情况下,使用[字典](data_structures.md)去做更快)

## while语句

如果条件为真,`while`语句允许您多次执行一个代码块。`while`语句是被称为**循环语句**的一种。`while`语句可以有一个可选的`else`子句。

例如 (保存为while.py):

```python
number = 23
running = True
while running:
guess = int(input('输入一个整数 : '))
if guess == number:
print('恭喜,你猜对了。')
# 这使while循环停止
running = False
elif guess < number:
print('不对,你猜的有点儿小。')
else:
print('不对,你猜的有点儿大。')
else:
print('while循环结束。')
# 在这做你想做的任何事
print('完成')
```

输出:

```shell

C:>\ python while.py

输入一个整数 : 50

不对,你猜的有点儿大。

输入一个整数 : 22

不对,你猜的的点儿小。

输入一个整数 : 23

恭喜,你猜对了。

while循环结束。

完成

```

**它是如何工作的:**

在这个程序中,我们继续玩猜谜游戏。比上一个程序进步的一点在于,允许用户一直猜直到他猜对——每次猜测不需要向上一个程序那样重新运行。这演示了如何正确的使用`while`语句。

我们移动`input`和`if`语句到`while`循环中,在`while`循环前,设置变量`running`为`True`。首先,我们检测变量`running`是否为`True`,然后继续执行相应的**while代码块**。在这个块执行完后,再检测条件。如果这时变量`running`为真,我们就再次执行while代码块;否则,我们执行可选的else代码块,然后执行下面的语句。

当`while`循环的条件变为`False`时执行`else代码块`,这也可能发生在第一次条件检测时。如果你使用`break`语句退出循环的话,那么`else`子句就不会被执行,否则当`while`循环的条件变为`False`时就会执行。

在这里`True`和`False`被称为布尔类型,你可以认为它们分别相当于值`1`和`0`。

> **C/C++程序员注意:**

> 记住, while循环可以有else子句。

## `for`循环

`for..in`语句是另一个循环语句,它**迭代**一个序列中的每一个对象。在后面的章节,我们将会看到更多关于[序列](data_structures.md)的细节。现在你需要知道的是:序列是一个有序的对象的集合。

例如 (保存为 for.py):

```python
for i in range(1, 5):
print(i)
else:
print('for循环结束')
```

输出:

```

$ python for.py

1

2

3

4

for循环结束

```

**它是如何工作的:**

在这个程序里,我们打印了一个数字的**序列**。我们使用内置的`range`函数生成了这个数字序列。

我们给`range`函数提供了两个数字作为参数,`range`返回一个从第一个数字到第二个数字的一个数字序列。例如, `range(1,5)`给出序列`[1, 2, 3, 4]`。默认情况下,`range` 步长值为1。如果我们为`range`函数提供第三个参数,那么这个参数就是新的步长值。例如`range(1,5,2)`得到`[1, 3]`。请记住,数字的范围小于第二个参数,即它**不**包括第二个数字。

注意,在for循环中`range()`一次只生成一个数字。如果你想立刻看到完整的数字序列,使用`list(range())`。例如, `list(range(5))` 会输出 `[0, 1, 2, 3, 4]`。list(列表)将在[数据结构](data_structures.md)中做更加详细的解释。

`for`循环然后遍历这个范围,`for i in range(1,5)`相当于 `for i in [1, 2, 3, 4]`,这就像把序列中的每一个数(或对象)分配给`i`,一次一个,然后为使用这个`i`值执行该代码块。在本例中,我们只是简单的打印它的值。

记住,`else`子句是可选的。如果有`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`语句用来**跳出**一个循环语句,即停止执行一个循环语句,即使循环条件还没有成为`False`或序列还没有被完全遍历。

很重要的一点是,如果你**跳出**`for`或`while`循环,任何相应的循环else块是**不**执行的。

例子 (保存为break.py):

```python
while True:
s = input('输入一些东西 : ')
if s == 'quit':
break
print('字符串的长度是', len(s))
print('完成')
```

输出:

```

$ python break.py

输入一些东西: Programming is fun

字符串的长度是 18

输入一些东西: When the work is done

字符串的长度是 21

输入一些东西 : if you wanna make your work also fun:

字符串的长度是 37

输入一些东西 : use Python!

字符串的长度是 11

输入一些东西 : quit

完成

```

**它是如何工作的:**

在这个程序中,我们通过循环不断地获取用户的输入,并打印输入字符串的长度。我们提供一个特殊的条件--通过检查用户输入是否是`quit`来结束程序。我们通过**跳出**循环停止程序,到达程序的结束位置。

获得字符串的长度可以使用内建的`len`函数。

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

**Swaroop 的诗意的Python**

在这里输入一个我写的迷你诗:

```

编程自有颜如玉

每当工作完成时

如你也想颜如玉:

使用Python!

```

## continue语句
`continue`语句是用来告诉Python跳过当前循环代码块中其余的语句,**继续**循环的下一次迭代。
例子 (保存为continue.py):
```python
while True:
s = input('输入一些东西: ')
if s == 'quit':
break
if len(s) < 3:
print('太小')
continue
print('输入的东西有足够的长度')
# 在这做其它各种处理...
```

输出:

```

$ python continue.py

输入一些东西: a

太小

输入一些东西: 12

太小

输入一些东西: abc

输入的东西有足够的长度

输入一些东西: quit

```

**它是如何工作的:**

在这个程序中,我们接受来自用户的输入,但是只有在输入的字符串至少3个字符时才处理。因此,我们使用内建的`len`函数来获得长度,如果长度小于3,通过使用`continue`句,我们跳过代码块中的其余语句。否则,在循环中的其余语句将被执行--这里可以进行其他的处理。

注意,`continue`语句同样适用于`for`循环。

### 小结

我们已经看到了如何使用三个控制流语句--`if`、`while`和`for`以及与它们相关的 `break`和`continue`语句。由于这些都是Python最常用的部分,你需要尽快和他们混得熟一点。

接下来,我们将学习如何创建和使用函数。