豆仓只装得下两百份,队伍却不管它什么时候见底。while 循环可以盯着余量,但除了它没人会去改这个数。哪个条件该结束这一班?
while 循环会在条件为真时持续运行。当你事先不知道要重复多少次时,它比 for 更合适。代价是:你必须自己更新条件,否则循环永远不会结束。 你还会用循环不变式、受限重试和工作队列,检查循环是否真的会结束。
条件控制循环
每次迭代前,Python 都会检查条件。条件为真时执行循环体;为假时结束循环。通常会在循环体里修改计数器,让条件最终变成假。
count = 3
while count > 0:
print(count)
count -= 1
print("Liftoff")倒计时
break 与 continue
break 会立即离开循环。continue 会跳过当前迭代剩下的代码,回到条件判断。两者都不要滥用,否则循环的出口会变得难以追踪。
n = 0
while n < 6:
n += 1
if n == 2:
continue
if n == 5:
break
print(n)跳过与停止
用 while 遍历序列
需要手动控制位置时,可以用索引配合 while。每次迭代都要更新索引。如果只是想访问每个元素,for 通常更清楚。
orders = ["latte", "tea", "mocha"]
i = 0
while i < len(orders):
print(orders[i])
i += 1手动迭代
用循环不变式解释总和
每轮开始时,total 是前 i 个价格的总和。循环体加上一个价格,再让 i 加一,于是下一轮开始时这句话仍然成立。写循环前先说清这个不变式;说不清,通常说明循环的形状不对。
prices = [4.5, 3.0, 2.5]
total = 0
i = 0
while i < len(prices):
total += prices[i]
i += 1
print(total)
print("processed", i, "of", len(prices))不变式让循环可以被检查
给重试设置预算
校验循环既需要成功出口,也需要次数上限。把尝试次数和值分开记录;成功就停,预算用完也停。打印停止原因,失败才不会悄悄消失。
raw_values = ["many", "3", "5"]
attempts = 0
value = None
while attempts < len(raw_values):
raw = raw_values[attempts]
attempts += 1
try:
value = int(raw)
break
except ValueError:
print("retry after", raw)
print("value", value, "attempts", attempts)成功或次数用完时停止
一次取一个,排空队列
while 适合处理会不断减少的工作。pop() 每次移除一项,列表越来越短,空列表为假,循环自然结束。不要在 for 遍历列表时追加元素;要改变工作集合,就显式移除。
queue = ["latte", "tea", "mocha"]
served = []
while queue:
order = queue.pop()
served.append(order)
print("serving", order)
print("served", served)每轮移除一项,空列表结束循环
本课要点
- while 在每次迭代前检查条件。
- 循环体必须让条件逐步变为假。
- break 退出循环,continue 跳到下一次迭代。
- 已经有集合可以遍历时,优先用 for。
- 循环不变式说明什么始终为真;每轮只做一次朝向终点的更新。
常见错误
- 忘记更新计数器,造成死循环。
- 在条件里用 = 而不是 ==。
- 把计数器更新写在循环体外面。
- 只更新总和却忘了更新索引,循环永远到不了终点。
用 while 循环把 1 到 5 相加,然后打印总和。
动手试试
改改变量、先预测输出,再运行代码。第一次点击“运行代码”时会下载 Python 运行时,可能需要几秒钟。
练习本课
12 道题,作答后立即看到解释。