4. 控制流

除了前面介绍的 while语句,Python 也有其它语言常见的流程控制语句,但是稍有不同。

4.1. if 语句

也许最知名的语句类型是if语句。例如:

>>> x = int(input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
...     x = 0
...     print('Negative changed to zero')
... elif x == 0:
...     print('Zero')
... elif x == 1:
...     print('Single')
... else:
...     print('More')
...
More

可以有零个或多个 elif 部分,else 部分是可选的。关键字 'elif' 是 'else if' 的简写,可以有效避免过深的缩进。if...elif ...elif ... 序列用于替代其它语言中 switch 或case 语句。

4.2. for 语句

Python 中的for语句和你可能熟悉的 C 或 Pascal 中的有点不同。和常见的依据一个等差数列迭代(如 Pascal),或让用户能够自定义迭代步骤和停止条件(如 C)不一样,Python 的 for 语句按照元素出现的顺序迭代任何序列(列表或字符串)。例如(没有双关意):

>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
...     print(w, len(w))
...
cat 3
window 6
defenestrate 12

如果要在循环内修改正在迭代的序列(例如,复制所选的项目),建议首先制作副本。迭代序列不会隐式地创建副本。 使用切片就可以很容易地做到:

>>> for w in words[:]:  # Loop over a slice copy of the entire list.
...     if len(w) > 6:
...         words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']

4.3. range() 函数

如果你确实需要遍历一个数字序列,内置函数range()很方便。它会生成等差序列:

>>> for i in range(5):
...     print(i)
...
0
1
2
3
4

给定的终点永远不会在生成的序列中;若要依据索引迭代序列,你可以结合使用range()len() ,如下所示:也可以让 range 函数从另一个数值开始,或者可以指定一个不同的步进值(甚至是负数,有时这也被称为‘步长’):

range(5, 10)
   5 through 9

range(0, 10, 3)
   0, 3, 6, 9

range(-10, -100, -30)
  -10, -40, -70

若要依据索引迭代序列,你可以结合使用range ()len() ,如下所示:

>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
...     print(i, a[i])
...
0 Mary
1 had
2 a
3 little
4 lamb

然而,在这种情况下,大部分时候使用enumerate()函数会更加方便,请参见Looping Techniques

如果你只打印range,会出现奇怪的结果:

>>> print(range(10))
range(0, 10)

range()返回的对象的行为在很多方面很像一个列表,但实际上它并不是列表。当你迭代它的时候它会依次返回期望序列的元素,但是它不会真正产生一个列表,因此可以节省空间。

我们把这样的对象称为可迭代的,也就是说它们适合期望连续获得元素的函数和构造器,直到穷尽。我们已经看到for语句是这样的一个迭代器list()函数是另外一个;它从可迭代对象创建列表。

>>> list(range(5))
[0, 1, 2, 3, 4]

后面我们会看到更多返回可迭代对象和以可迭代对象作为参数的函数。

4.4. breakcontinue 语句,以及循环中 else 字句

Break 语句和 C 中的类似,用于跳出最近的forwhile 循环。

循环语句可以有一个 else 子句;当 (for) 循环迭代完整个列表或(while)循环条件变为 false,而非由break 语句终止时,它会执行。下面循环搜索质数的代码例示了这一点:

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

(是的,这是正确的代码。看仔细:else子句属于for 循环,属于 if 语句。)

当使用一个循环, else子句已更像的else子句的try语句而不是,if语句: try语句的else子句时未发生任何异常,和一个循环else子句运行不会中断发生时运行。

更多关于try语句和异常的内容,请参见处理异常continue 语句,也是从 C 语言借来的,表示继续下一次迭代:

>>> for num in range(2, 10):
...     if num % 2 == 0:
...         print("Found an even number", num)
...         continue
...     print("Found a number", num)
Found an even number 2
Found a number 3
Found an even number 4
Found a number 5
Found an even number 6
Found a number 7
Found an even number 8
Found a number 9