2.13. 循环控制¶
有两个关键字可以改变循环的运行方式:
break—— 立即退出循环。continue—— 跳过当前迭代的剩余部分,开始下一次迭代。
二者都作用于它们所在的最内层循环。
2.13.1. break¶
使用 break 在某个条件满足时立刻停止循环。这是经典的“查找并停止”模式:
found = None
for item in items:
if matches(item):
found = item
break
if found is not None:
print("found:", found)
在 while True: 循环中,break 就是结束循环的方式:
while True:
line = next_line()
if line == "quit":
break
process(line)
2.13.2. continue¶
使用 continue 跳过循环体的剩余部分,直接进入下一次迭代。这对于在循环内部筛选元素很方便:
for n in numbers:
if n < 0:
continue # skip negatives
print(n)
同样的效果也可以用一个包裹循环体剩余部分的 if 块来实现。当跳过条件比保留条件更容易事先说清楚时,continue 有时会更清晰。
在循环内部,continue 扮演的角色与函数中提前 return 相同:跳过你不处理的情况,让主要工作保持在外层缩进上、平铺展开。这种先筛选再处理的循环是其典型形态:
for item in items:
if item is None:
continue
if not item.is_valid():
continue
process(item)
缩进后的 process(item) 那一行才是真正的工作;上面每一个守卫语句都明确说明了哪些元素会被跳过。
2.13.3. 循环上的 else¶
for 和 while 都接受一个可选的 else 块。它会在循环没有触发 break 而正常结束时运行。最常见的用途是一个查找循环,希望在什么都没找到时有一个兜底处理:
for item in items:
if matches(item):
print("found:", item)
break
else:
print("no match")
如果触发了 break,else 块就会被跳过。可以把这个结构读作“for X in Y: ...;否则,如果我们从未跳出循环,就执行 Z。”
2.13.4. 常见的循环模式¶
在实际脚本中,有几种模式经常出现:
轮询 —— 在继续往下走之前,等待某个条件变为真。循环体使用
pass,即 Python 的空操作语句;每个缩进块都必须至少包含一条语句,而pass正是表示“这里什么都不做”的方式:while not ready(): pass proceed()
状态机 —— 一个单独的
while True:循环,根据状态变量来决定要做什么。当工作能够干净地拆分为几个命名阶段时,它很有用:state = "header" for line in lines: if state == "header": if line.startswith("---"): state = "body" elif state == "body": print(line)
累加 —— 在遍历一个序列的同时逐步构建结果:
total = 0 for x in samples: total += x mean = total / len(samples)
许多累加循环都有使用内置函数的单行等价写法。当某个内置函数适用时,就直接使用它:
sum()—— 将可迭代对象中的每个元素相加。any()—— 只要至少有一个元素为真值就返回True。all()—— 只有当每个元素都为真值时才返回True。sorted()—— 一个按顺序排列了这些元素的新列表。len()—— 元素的数量(前提是该可迭代对象知道自己的长度)。
>>> samples = [3, 1, 4, 1, 5, 9, 2, 6] >>> sum(samples) 31 >>> sum(samples) / len(samples) # mean 3.875 >>> max(samples) 9 >>> min(samples) 1 >>> sorted(samples) [1, 1, 2, 3, 4, 5, 6, 9] >>> any([False, False, True]) True >>> all([True, True, False]) False
内置版本更简短、更清晰,而且通常比手写同样的循环更快。