1.3 控制流:让账本学会判断与循环


1.3 控制流:让账本学会判断与循环

本节摘要:默认情况下代码从上到下一行行执行,但真实程序必须"看情况办事":输入不同指令走不同分支,批量任务用循环重复。本节讲 if 分支、while 循环、for 遍历三件套,并把它们拧成轻记账 v0.1 的交互主循环——程序启动后反复等待指令,直到用户说退出。这一节写完,你的脚本第一次有了"应用"的样子。

读完这节能做什么

阅读完本节,你应当能够:

  1. 用 if / elif / else 处理多分支指令
  2. 用 while 写"持续运行直到退出"的主循环
  3. 用 for 遍历账目列表并区分 break 与 continue
  4. 把分支与循环组合成交互式程序骨架

问题:程序凭什么"看情况办事"

上一节的脚本只会从头跑到尾:打印汇总、结束。可你想要的账本是对话式的——敲"记"就记账,敲"查"就汇总,敲"退"才退出。这需要两种新能力:按条件选路(分支)和把一段代码反复执行(循环)。所有编程语言的控制流都是这两件事的组合,Python 用缩进来划定每个分支和循环的边界,这是它和其他语言最直观的不同。

if:按条件选路

command = "查" if command == "记": print("进入记账流程") elif command == "查": print("显示账目汇总") elif command == "退": print("再见") else: print("没听懂这个指令")

三个细节值得嚼一嚼。其一,== 是比较,= 是赋值,写混是终身高频笔误。其二,elif 是"否则如果",逐条往下试,命中一条就跳过其余,所以条件的排列顺序就是优先级。其三,else 兜底处理"意料之外",交互程序里它常用来提示无效输入——轻记账的 else 正是这个用途。

条件本身由比较与逻辑运算符组成:><>=!=,以及"并且" and、"或者" or、"取反" not。例如"金额超过 100 并且未报销"写成 amount > 100 and not is_refunded

while:不知道循环几次时的选择

交互程序的特点是:你不知道用户会敲多少条指令,只知道"没敲退出就继续"。这正是 while 的适用场景——条件成立就一直转

running = True while running: command = input("请输入指令(记 / 查 / 退):") if command == "退": running = False # 下一轮循环条件不成立,退出 elif command == "记": print("记账功能稍后实现") else: print("暂不支持", command) print("程序结束")

input() 会暂停程序等用户敲字,敲完回车返回一个字符串。运行这段代码,程序就"活"了:你敲什么它应什么,敲"退"才停。轻记账的主循环骨架就是这个形状,后面每一章都只是往循环的分支里填更丰满的实现。

for:遍历已知集合

上一节末尾出现过它,现在拆开讲。for 把列表里的元素逐个取出:

ledger = [ {"item": "早饭", "amount": 12.5}, {"item": "地铁", "amount": 4.0}, {"item": "奶茶", "amount": 18.0}, ] total = 0 big = [] for record in ledger: total += record["amount"] # += 是累加简写 if record["amount"] >= 10: big.append(record["item"]) print(f"合计 {total} 元") # 合计 34.5 元 print("大额消费:", big) # 大额消费: ['早饭', '奶茶']

循环体里也可以用分支,这正是"控制流组合"的含义。两个控制词的区别要用场景记:

for record in ledger: if record["amount"] < 5: continue # 小额的跳过,继续下一笔 if total > 100: break # 累计超 100,整个循环提前结束 total += record["amount"]

continue 跳过本轮剩余语句进入下一轮;break 直接终止整个循环。再介绍一个高频搭档 range

for i in range(1, 4): # 1、2、3,含头不含尾 print(f"第 {i} 天")

演练:拼出 v0.1 完整版

把分支、循环、上一节的数据结构全部接起来,这就是全书项目的起点:

ledger = [] total = 0.0 running = True while running: command = input("指令(记 / 查 / 退):") if command == "记": item = input("用途:") amount = float(input("金额:")) ledger.append({"item": item, "amount": amount}) print(f"已记:{item} {amount} 元") elif command == "查": for i, record in enumerate(ledger, start=1): print(f"{i}. {record['item']} {record['amount']} 元") print(f"共 {len(ledger)} 笔,合计 {sum(r['amount'] for r in ledger):.1f} 元") elif command == "退": running = False else: print("指令无效,请输入 记 / 查 / 退") print("账本已关闭")

一次完整会话的输出长这样:

指令(记 / 查 / 退):记 用途:早饭 金额:12.5 已记:早饭 12.5 元 指令(记 / 查 / 退):查 1. 早饭 12.5 元 共 1 笔,合计 12.5 元 指令(记 / 查 / 退):退 账本已关闭

变式一:加一个"删"指令,输入序号删除对应账目,注意删完序号会整体前移。变式二:故意在金额处输入"abc",程序当场崩溃——float() 转不动非数字字符串。这个崩溃不是意外,是下一节异常处理的正式出场理由。

易错点清单

  • 缩进不一致:同一段代码块里空格数必须一致,混用缩进层级会报 IndentationError 或产生逻辑错误
  • 条件顺序:范围判断从宽到窄排列,若先写 amount > 0 再写 amount > 100,后者永远轮不到
  • while 忘记改变条件:条件永远为真就死循环,running = False 这类"出口语句"别漏
  • for 里改正在遍历的列表:边遍历边增删元素会跳项,先收集要删的,遍历完再删

本节要点回顾

  • if / elif / else 处理分支,条件从上到下短路命中
  • while 适合"不知道多少次"的循环,交互主循环是它的招牌用法
  • for 遍历集合enumerate 同时拿序号与元素
  • continue 跳过本轮,break 终止循环
  • 轻记账 v0.1 完成:while 主循环 + 三分支指令,但金额输入错误会让它崩溃

脚本能对话了,却经不起一次手滑。下一节专门处理"程序崩了怎么办"之前的铺垫先放一放,我们先让账目在两次运行之间活下来——文件与持久化。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U