2.1.5 流程控制

这一节学习让程序“做判断”和“重复执行”。条件判断和循环是所有自动化脚本、数据处理流程和模型训练代码的骨架,掌握它们后,你的代码就不再只是从上到下执行。
- 掌握
if/elif/else条件判断 - 掌握
for循环和while循环 - 学会使用
break、continue控制循环 - 能编写包含嵌套逻辑的程序
什么是流程控制?
Section titled “什么是流程控制?”到目前为止,你写的代码都是从上到下一行一行执行的。但真实的程序需要做判断、需要重复执行——这就是流程控制。
想象你早上出门的决策过程:
如果 下雨了: 带伞否则如果 太阳很大: 戴帽子否则: 直接出门这就是条件判断。
再想象你背单词:
重复 100 次: 看一个新单词 记住它这就是循环。
条件判断:if / elif / else
Section titled “条件判断:if / elif / else”基本的 if
Section titled “基本的 if”failed_tests = 3
if failed_tests > 0: print("暂停发布,先检查失败的测试。")语法规则:
if后面跟条件表达式- 条件后面有一个冒号
:(很多新手会忘记) - 条件成立时执行的代码需要缩进 4 个空格
if…else
Section titled “if…else”all_checks_passed = False
if all_checks_passed: print("构建可以部署") print("编写发布说明")else: print("构建继续保持评审状态") print("先修复失败的检查")if…elif…else
Section titled “if…elif…else”elif 是 “else if” 的缩写,用来检查多个条件:
latency_ms = 185
if latency_ms < 100: status = "很快"elif latency_ms < 200: status = "健康"elif latency_ms < 500: status = "偏慢"else: status = "严重"
print(f"API 延迟: {latency_ms} ms,状态: {status}")# 输出: API 延迟: 185 ms,状态: 健康条件判断的简写
Section titled “条件判断的简写”# 三元表达式(一行搞定简单的 if-else)latency_ms = 185status = "在预算内" if latency_ms <= 200 else "需要关注"print(status) # 在预算内
# 等价于if latency_ms <= 200: status = "在预算内"else: status = "需要关注"嵌套的 if
Section titled “嵌套的 if”条件里面可以再套条件:
has_approval = Trueall_tests_passed = False
if has_approval: if all_tests_passed: print("部署这个构建") else: print("等待测试套件通过")else: print("先申请发布审批")不过嵌套太多层会让代码难以阅读,通常不建议超过 3 层。
for 循环
Section titled “for 循环”for 循环用来遍历一个序列(列表、字符串、范围等)中的每个元素。
services = ["登录 API", "搜索 API", "Worker", "仪表盘"]
for service in services: print(f"检查 {service}")
# 输出:# 检查 登录 API# 检查 搜索 API# 检查 Worker# 检查 仪表盘理解方式:for service in services 的意思是”对于 services 中的每一个 service,执行下面的代码”。
word = "Python"
for char in word: print(char, end=" ")
# 输出: P y t h o nrange() 函数
Section titled “range() 函数”range() 生成一个数字序列,是 for 循环最常用的搭档:
# range(5) 生成 0, 1, 2, 3, 4for i in range(5): print(i, end=" ")# 输出: 0 1 2 3 4
# range(start, stop) 从 start 到 stop-1for i in range(1, 6): print(i, end=" ")# 输出: 1 2 3 4 5
# range(start, stop, step) 带步长for i in range(0, 10, 2): print(i, end=" ")# 输出: 0 2 4 6 8
# 倒数for i in range(5, 0, -1): print(i, end=" ")# 输出: 5 4 3 2 1实际案例:统计评审时间
Section titled “实际案例:统计评审时间”total_minutes = 0for day in range(1, 6): total_minutes += 30print(f"5 天评审总分钟数: {total_minutes}") # 150enumerate():同时获取索引和值
Section titled “enumerate():同时获取索引和值”tasks = ["设计登录表单", "构建 API 接口", "编写冒烟测试"]
# 普通写法for i in range(len(tasks)): print(f"任务 {i+1}: {tasks[i]}")
# 更 Pythonic 的写法:用 enumeratefor i, task in enumerate(tasks): print(f"任务 {i+1}: {task}")
# 指定起始编号for i, task in enumerate(tasks, start=1): print(f"任务 {i}: {task}")while 循环
Section titled “while 循环”while 循环在条件成立时持续执行,直到条件不成立为止。
count = 0
while count < 5: print(f"当前计数: {count}") count += 1 # 别忘了更新条件!
print("循环结束")
# 输出:# 当前计数: 0# 当前计数: 1# 当前计数: 2# 当前计数: 3# 当前计数: 4# 循环结束while 的典型场景
Section titled “while 的典型场景”while 适合不确定循环次数的情况:
# 场景:等待后台任务完成job_status = "queued"poll_count = 0
while job_status != "finished": poll_count += 1 print(f"第 {poll_count} 次轮询: {job_status}")
if poll_count == 1: job_status = "running" elif poll_count == 2: job_status = "finished"
print(f"任务在 {poll_count} 次轮询后完成")for vs while 怎么选?
Section titled “for vs while 怎么选?”| 场景 | 推荐 | 原因 |
|---|---|---|
| 遍历列表/字符串 | for | 天然适合 |
| 循环固定次数 | for + range() | 简洁明确 |
| 不确定循环次数 | while | 灵活控制 |
| 等待某个条件成立 | while | 自然直觉 |
经验法则:能用 for 就用 for,它更安全(不会死循环)。
break 和 continue
Section titled “break 和 continue”break:立即终止循环
Section titled “break:立即终止循环”# 找到第一个慢请求就停下latencies_ms = [120, 145, 310, 180, 260]
for latency_ms in latencies_ms: if latency_ms > 250: print(f"第一个慢请求: {latency_ms} ms") break print(f"{latency_ms} ms 仍在范围内,继续检查...")
# 输出:# 120 ms 仍在范围内,继续检查...# 145 ms 仍在范围内,继续检查...# 第一个慢请求: 310 mscontinue:跳过本次循环,继续下一次
Section titled “continue:跳过本次循环,继续下一次”# 只打印慢请求,跳过健康请求latencies_ms = [95, 210, 180, 260, 130]
for latency_ms in latencies_ms: if latency_ms <= 200: continue # 跳过健康请求 print(latency_ms, end=" ")
# 输出: 210 260break 和 continue 的区别
Section titled “break 和 continue 的区别”# break:直接离开循环for i in range(10): if i == 5: break # 循环到 5 就整个停了 print(i, end=" ")# 输出: 0 1 2 3 4
# continue:跳过当前,继续下一个for i in range(10): if i == 5: continue # 跳过 5,继续 6, 7, 8, 9 print(i, end=" ")# 输出: 0 1 2 3 4 6 7 8 9循环中的 else
Section titled “循环中的 else”Python 的循环有一个独特的 else 子句——当循环正常结束(不是被 break 终止)时执行:
# 检查是否缺少必要评审completed_checks = ["unit-test", "lint", "api-test"]required_check = "security-review"
for check in completed_checks: if check == required_check: print(f"{required_check} 已完成") breakelse: # 循环没有被 break 终止,说明没有找到必要检查 print(f"{required_check} 缺失")
# 输出: security-review 缺失循环里面可以再套循环:
# 打印模块/检查矩阵modules = ["API", "UI", "DB"]checks = ["lint", "test"]
for module in modules: for check in checks: print(f"{module}:{check}", end="\t") print() # 每个模块结束后换行输出:
API:lint API:testUI:lint UI:testDB:lint DB:test案例 1:模拟 AI 模型训练过程
Section titled “案例 1:模拟 AI 模型训练过程”import random
print("=== 开始训练模型 ===")print(f"{'Epoch':<10}{'Loss':<15}{'Accuracy':<15}{'Status'}")print("-" * 50)
loss = 2.5accuracy = 0.10
for epoch in range(1, 21): # 模拟训练:损失逐渐下降,准确率逐渐上升 loss *= random.uniform(0.85, 0.95) accuracy = min(accuracy + random.uniform(0.03, 0.06), 1.0)
# 判断训练状态 if accuracy >= 0.95: status = "✅ 达标" elif accuracy >= 0.80: status = "📈 良好" else: status = "🔄 训练中"
print(f"{epoch:<10}{loss:<15.4f}{accuracy:<15.2%}{status}")
# 如果准确率达到 98%,提前停止 if accuracy >= 0.98: print(f"\n提前停止!在第 {epoch} 轮达到目标准确率") breakelse: print(f"\n训练完成!最终准确率: {accuracy:.2%}")案例 2:密码强度检查器
Section titled “案例 2:密码强度检查器”password = input("请输入密码: ")
has_upper = False # 是否有大写字母has_lower = False # 是否有小写字母has_digit = False # 是否有数字has_special = False # 是否有特殊字符
for char in password: if char.isupper(): has_upper = True elif char.islower(): has_lower = True elif char.isdigit(): has_digit = True else: has_special = True
# 计算强度分数score = 0if len(password) >= 8: score += 1if has_upper: score += 1if has_lower: score += 1if has_digit: score += 1if has_special: score += 1
# 输出结果print(f"\n密码强度: {'★' * score}{'☆' * (5 - score)} ({score}/5)")
if score <= 2: print("弱密码!建议加强")elif score <= 4: print("中等强度")else: print("强密码!")练习 1:发布检查标签
Section titled “练习 1:发布检查标签”用一个小的发布检查标签器练习分支顺序:
打印 1 到 50 的样本编号,但是:
- 如果数字能被 15 整除,打印 “FullCheck”
- 如果数字能被 3 整除,打印 “Lint”
- 如果数字能被 5 整除,打印 “Test”
- 其他情况打印数字本身
for i in range(1, 51): if i % 15 == 0: print("FullCheck") elif i % 3 == 0: print("Lint") elif i % 5 == 0: print("Test") else: print(i)提示:先判断能否被 15 整除,再判断 3 和 5。
练习 2:延迟告警循环(限制样本数)
Section titled “练习 2:延迟告警循环(限制样本数)”最多检查 7 个延迟样本,一旦超过阈值就停止。
latencies_ms = [120, 180, 260, 140, 310, 190, 170]threshold_ms = 250max_samples = 7
for sample_no, latency_ms in enumerate(latencies_ms[:max_samples], start=1): print(f"样本 {sample_no}: {latency_ms} ms")
if latency_ms <= threshold_ms: print("健康") continue
print("告警:延迟超过阈值") breakelse: print("已检查的样本都在阈值内。")练习 3:打印部署进度条
Section titled “练习 3:打印部署进度条”用循环打印以下进度形状:
###############然后试着打印倒计时进度条:
###############练习 4:找出失败检查
Section titled “练习 4:找出失败检查”打印所有状态不是 "passed" 的检查名称。
checks = [ ("lint", "passed"), ("unit-test", "failed"), ("api-test", "passed"), ("security-review", "failed"),]
for check_name, status in checks: if status == "passed": continue print(f"{check_name}: {status}")参考实现与讲解
- 发布检查标签要先判断能否被
15整除,否则15可能会提前输出成Lint或Test。 - 延迟列表先用固定数据测试:健康路径、告警路径,以及把慢请求移走后的全部通过路径。
- 进度条可以用
for n in range(1, 6): print("#" * n)打印,倒计时则用反向range。 - 失败检查筛选应对
"passed"使用continue,只打印failed或其他非通过状态。 - 注意边界错误:
range(1, 51)包含50,range(1, 50)不包含50。
学完这一页,至少保留这张证据卡:
- 概念
- 变量、类型、运算符、输入/输出、分支、循环、结构、函数或模块
- 代码
- 用于说明该概念的最小可运行 Python 代码片段
- 输出
- 打印值、类型、分支结果、循环 trace,或返回值
- 失败检查
- 类型不匹配、缩进错误、越界、可变数据或导入路径问题
- 期望产出
- 代码和打印结果,证明概念可行
| 语法 | 用途 | 关键点 |
|---|---|---|
if/elif/else | 条件判断 | 条件从上到下检查,冒号和缩进不能忘 |
for...in | 遍历序列 | 配合 range()、列表、字符串使用 |
while | 条件循环 | 注意更新条件,避免死循环 |
break | 终止循环 | 立即跳出整个循环 |
continue | 跳过本次 | 跳过当前迭代,继续下一次 |
range() | 生成数字序列 | range(start, stop, step) |