---
jupyter:
jupytext:
text_representation:
extension: .md
format_name: markdown
format_version: '1.2'
jupytext_version: 1.3.0rc2
kernelspec:
display_name: Python 3
language: python
name: python3
---
.. meta::
:description: Topic: Contorl flow with for-loops and while-loops, Difficulty: Easy, Category: Section
:keywords: for-loop, while-loop, break, control flow, basic programming
# For循环和While循环
在本节中我们将会介绍“for循环”控制流以及“可迭代物”(iterable)的正式定义。这些功能极其强大强大。在未来,你会在你编写的Python代码中随处见到这些概念!
**注**:
在本资源各处会有一些阅读理解练习。这些题目旨在帮助读者活学活用文中的知识点。练习题的答案可以在本页底部找到。
## For循环
一个“for循环”(for-loop)允许我们迭代某个集合中的成员,并为每一次成员执行同一块代码。比如说,以下的代码会求元组中所有正数的和:
```python
total = 0
for num in (-22.0, 3.5, 8.1, -10, 0.5):
if num > 0:
total = total + num
```
“for循环”的语法为:
```
for in :
一区块代码
```
`` 指代任何合法的变量身份(variable-identifier),`` 则是任何**可迭代物**。我们会在下一节中更正式地讨论迭代物;现在你只需要知道任何序列都是可迭代物这一事实就行了。`for` 语句必须由一个冒号结尾,且for循环的主体必须由[空格限定](https://cn.pythonlikeyoumeanit.com/Module2_EssentialsOfPython/Introduction.html#Python使用空格来限定区域)。
for循环的行为如下:
- 试图获取可迭代物的下一个成员。
- 如果可迭代物是空的,退出for循环且不运行其主体代码。
- 如果可迭代物提供了一个成员,为 `` 赋值为该成员(如果 `` 在之前并没有被定义,它将会在这里被定义)。
- 执行循环的主体代码。
- 返回第一步。
让我们来看一看一个例子吧:
```python
# 演示基本的for循环
total = 0
for item in [1, 3, 5]:
total = total + item
print(total) # `total` 的值为 1 + 3 + 5 = 9
# `item` 在这里依然被定义,且其值为5
```
此代码会执行以下的步骤:
1. 定义变量 `total`,并为其赋值 `0`
2. 迭代此列表,得出值 `1`,定义变量 `item` 并为其赋值 `1`
3. 为 `total` 赋值 `0 + 1`
4. 迭代此列表,得出值 `3` 并为 `item` 赋值该数字
5. 为 `total` 赋值 `1 + 3`
6. 迭代此列表,得出值 `5` 并为 `item` 赋值该数字
7. 为 `total` 赋值 `4 + 5`
8. 迭代此列表。因为现在已经在列表结尾,列表将提供一个 `StopIteration` 信号,并导致for循环退出
9. 打印 `total` 的值(9)
#### 可能的错误
注意迭代变量 `item` 在for循环退出之后依然存在。它会引用for循环迭代的最后一个值(在这个例子中 `item` 的值为5)。就算如此,*你不应该在for循环外面使用迭代变量*。因为如果你循环一个*空*的可迭代物,迭代变量不会被定义:
```python
for x in []: # 可迭代物是空的——迭代变量 `x` 将不会被定义
print("Hello?") # 此代码不会被执行
print(x) # 程序报错,因为 `x` 没有被定义
```
当我们试图迭代一个空列表时,程序会在变量 `x` 被定义之前立刻收到 `StopIteration` 信号。for循环中的代码块一次都没有被执行。因为 `x` 没有被定义,之后的 `print(x)` 语句会导致 `NameError`!
**阅读理解:简单for循环**
使用一个for循环和一个if语句,打印字符串 `"abcdefghij"` 中的每一个元音(vowel,也就是aeiou这几个字母)。
## While循环
一个“while循环”(while-loop)允许你重复一区块代码,直到某个条件不再满足:
```
while :
代码块
```
`` 是一个会返回 `True` 或 `False` 的表达式,或任何可以转化为 `bool` 的对象。while循环的“主体”则是在循环语句下方缩进的代码。
while循环的行为如下:
- 执行 `bool()` 并在表达式返回 `True` 时执行下方缩进的代码区块。不然,“退出”while循环并跳过其缩进代码。
- 如果缩进的代码块被执行了,回到第一步。
让我们观察一个例子:
```python
# 演示基本的while循环
total = 0
while total < 2:
total += 1 # 和 `total = total + 1` 等值
print(total) # `total` 现在的值为 2
```
此代码会执行以下步骤:
1. 定义变量 `total`,并为其赋值 `0`
2. 运算 `0 < 2`,其返回 `True`:进入循环主体的代码块
3. 执行代码块:为 `total` 赋值 `0 + 1`
4. 运算 `1 < 2`,其返回 `True`:进入循环主体的代码块
5. 执行代码块:为 `total` 赋值 `1 + 1`
6. 运算 `2 < 2`,其返回 `False`:*跳过*循环主体的代码块
7. 打印 `total` 的值(2)
注意,如果我们一开始定义 `total = 3`,那条件表达式 `3 < 2` 会直接返回 `False`,且缩进的代码块将一次都不会执行。
**警告!**
你可能(一不小心)编写了条件语句永远为真的while循环。这会导致你的代码无限运行!如果这在Jupyter记事本中意外发生,打断或重启你的壳(kernel)。
**阅读理解:简单while循环**
设一列表 `x`,其成员皆为的非零正数。在列表的结尾附加列表所有值的和。重复进行这一步,直到 `x` 的最后一个成员的值至少是100。使用一个while循环。
如果你定义 `x = [1]`,那在你的while循环结束后 `x` 应该是 `[1, 1, 2, 4, 8, 16, 32, 64, 128]`。
## 循环中的 `break`,`continue`,和 `else` 句段
你可以在for循环和while循环的主体中使用 `continue` 和 `break` 语句。它们分别提供一些额外的“短路”和提前退出循环的方式。
在循环中遇到 `break` 会导致程序立刻退出循环:
```python
# 提前退出循环
>>> for item in [1, 2, 3, 4, 5]:
... if item == 3:
... print(item, " ...break!")
... break
... print(item, " ...next iteration")
```
```
1 ...next iteration
2 ...next iteration
3 ...break!
```
你可以在任何循环结尾添加一个 `else` 句段。此else语句的主体*只有在循环自然退出(没有被 `break` 语句打断)后才会执行*。
```python
# 在循环结尾添加一个else句段
>>> for item in [2, 4, 6]:
... if item == 3:
... print(item, " ...break!")
... break
... print(item, " ...next iteration")
... else:
... print("if you are reading this, then the loop completed without a 'break'")
```
```
2 ...next iteration
4 ...next iteration
6 ...next iteration
if you are reading this, then the loop completed without a 'break'
```
在循环中遇到 `continue` 语句会导致程序立刻回到检查条件语句这一步。
```python
# 演示循环中的 `continue` 语句
>>> x = 1
>>> while x < 4:
... print("x = ", x, ">> enter loop-body <<")
... if x == 2:
... print("x = ", x, " continue...back to the top of the loop!")
... x += 1
... continue
... x += 1
... print("--reached end of loop-body--")
```
```
x = 1 >> enter loop-body <<
--reached end of loop-body--
x = 2 >> enter loop-body <<
x = 2 continue...back to the top of the loop!
x = 3 >> enter loop-body <<
--reached end of loop-body--
```
**阅读理解:控制循环中的流**
重复循环一个整数列表,求其中偶数的和并将此和加到一个总值中。重复此过程,直到总值超过100,或已经循环这个列表超过50次。在总值大于等于100时打印它。
## 官方说明文档链接
- [“for”语句](https://docs.python.org/3/reference/compound_stmts.html#the-for-statement)
- [“while”语句](https://docs.python.org/3/reference/compound_stmts.html#the-while-statement)
- [“break”,“continue”,和“else”句段](https://docs.python.org/3/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops)
- [“pass”语句](https://docs.python.org/3/tutorial/controlflow.html#pass-statements)
## 阅读理解答案
**简单for循环:解**
```python
for letter in "abcdefghij":
if letter in "aeiou":
print(letter)
```
**简单while循环:解**
```python
while x[-1] < 100:
x.append(sum(x))
```
**控制循环中的流:解**
```python
x = [3, 4, 1, 2, 8, 10, -3, 0]
num_loop = 0
total = 0
while total < 100:
for item in x:
# 当 `item` 是奇数时立刻跳到
# 下一轮for循环
if item % 2 == 1:
continue
else:
total += item
num_loop += 1
# 只有在循环了50次之后才
# 打断while循环中
if 50 < num_loop:
break
else:
print(total)
```