03|分支与迭代:构建程序的决策引擎
场景引入:订单处理流水线
你正在为一个电商后台开发订单处理模块。每笔订单到达后,系统需要做出一系列判断:订单金额是否满足包邮条件?用户等级是否享受折扣?库存是否充足?同时,系统需要遍历订单中的每件商品,逐一计算价格、扣减库存。
这两种能力——根据条件走不同处理路径和对一组数据重复执行操作——正是本章的主题。
在计算机科学中,这些结构被称为控制流。几乎所有复杂程序,无论规模多大,都由三种基本结构组合而成:顺序执行、条件分支和循环迭代。
条件分支:if 语句
单条件判断
order_amount = 150
if order_amount >= 99:
print("符合包邮条件")
语法要点:
if关键字后写条件表达式,以冒号:结尾- 条件成立时执行的代码块必须缩进 4 个空格(Python 用缩进而非大括号来界定代码块)
二路分支:if…else
inventory = 0
if inventory > 0:
print("商品有货,可以下单")
print("正在处理订单...")
else:
print("商品缺货")
print("已加入到货通知列表")
多路分支:if…elif…else
member_level = "gold"
if member_level == "platinum":
discount = 0.7
print("尊享七折优惠")
elif member_level == "gold":
discount = 0.85
print("享受八五折优惠")
elif member_level == "silver":
discount = 0.9
print("享受九折优惠")
else:
discount = 1.0
print("暂无折扣")
**执行逻辑:**条件从上到下依次检查,命中第一个为真的分支后执行对应代码块,随后跳过所有剩余分支。如果没有任何条件成立,执行 else 块。
elif 和 else 都是可选的。
input() 与类型转换配合
input() 返回的始终是字符串。如果要做数值比较,必须先转换类型:
# 错误示范
raw = input("请输入商品数量:")
# if raw > 100: # TypeError:字符串不能和整数比较
# 正确做法
qty = int(input("请输入商品数量:"))
if qty > 100:
print("大宗订单,启用批发价")
else:
print("零售价")
条件表达式(三元运算)
简单的二选一判断可以压缩为一行:
stock = 5
label = "有货" if stock > 0 else "缺货"
print(label) # 有货
语法:值A if 条件 else 值B。条件为 True 时结果为值A,否则为值B。
条件嵌套
order_total = 200
has_coupon = True
if order_total >= 100:
if has_coupon:
print("满减 + 优惠券叠加")
else:
print("仅满减优惠")
else:
print("不满足优惠条件")
嵌套层数过多会降低可读性,尽量控制在两到三层以内。
比较运算符与逻辑运算符
比较运算符
比较运算符的结果是布尔值:
print(10 == 10) # True (等于)
print(10 != 7) # True (不等于)
print(10 > 7) # True (大于)
print(10 < 7) # False (小于)
print(10 >= 10) # True (大于等于)
print(10 <= 7) # False (小于等于)
关键区分:== 是比较运算符(判断两个值是否相等),= 是赋值运算符(将右侧的值绑定到左侧的变量上),两者含义完全不同。这是初学者最常犯的错误之一。
# 正确:用 == 做比较
if order_amount == 100:
print("金额正好是 100")
# 错误:在条件中使用 = 会导致语法错误
# if order_amount = 100: # SyntaxError!
逻辑运算符
当需要组合多个条件时,使用逻辑运算符:
balance = 5000
credit_score = 720
# and:所有条件均满足
if balance >= 1000 and credit_score >= 600:
print("审批通过")
# or:至少满足一个条件
weekday = "Saturday"
if weekday == "Saturday" or weekday == "Sunday":
print("周末模式")
# not:取反
is_blocked = False
if not is_blocked:
print("账户正常")
优先级:not > and > or。不确定时用括号明确意图:
if (balance >= 1000 and credit_score >= 600) or is_vip:
print("审批通过")
综合示例:系统登录验证
account = input("账号:")
secret = input("密码:")
if account == "operator" and secret == "s3cure!":
print("认证成功,欢迎进入管理面板")
elif account == "operator" and secret != "s3cure!":
print("密码不正确,请重试")
else:
print("账号不存在")
for 循环:遍历数据集合
基本语法
for 循环从序列中逐个取出元素:
products = ["键盘", "鼠标", "耳机"]
for item in products:
print(f"正在处理:{item}")
# 正在处理:键盘
# 正在处理:鼠标
# 正在处理:耳机
# 遍历字符串中的每个字符
for ch in "HTTP":
print(ch, end="-")
# H-T-T-P-
range() 生成数字序列
# range(n):0 到 n-1
for idx in range(4):
print(idx, end=" ")
# 0 1 2 3
# range(start, stop):start 到 stop-1
for val in range(5, 10):
print(val, end=" ")
# 5 6 7 8 9
# range(start, stop, step):指定步长
for even in range(0, 20, 2):
print(even, end=" ")
# 0 2 4 6 8 10 12 14 16 18
# 倒序
for countdown in range(10, 0, -1):
print(countdown, end=" ")
# 10 9 8 7 6 5 4 3 2 1
累加计算
# 计算 1 到 100 的累加和
accumulator = 0
for num in range(1, 101):
accumulator += num
print(f"1 到 100 的和为:{accumulator}")
# 1 到 100 的和为:5050
遍历字典
inventory = {"键盘": 45, "鼠标": 120, "显示器": 8}
# 遍历键
for product in inventory:
print(product)
# 遍历键值对
for product, qty in inventory.items():
print(f"{product}:库存 {qty} 件")
# 遍历值
for qty in inventory.values():
print(qty)
enumerate() 带索引遍历
task_list = ["部署服务", "配置数据库", "启动监控"]
for seq, task in enumerate(task_list):
print(f"步骤 {seq + 1}:{task}")
# 步骤 1:部署服务
# 步骤 2:配置数据库
# 步骤 3:启动监控
while 循环:条件驱动的重复
while 循环在条件为 True 时持续执行:
基本语法
retry = 1
while retry <= 3:
print(f"第 {retry} 次尝试连接...")
retry += 1
# 第 1 次尝试连接...
# 第 2 次尝试连接...
# 第 3 次尝试连接...
务必确保条件最终会变为 False,否则进入死循环。如遇死循环,按 Ctrl+C 强制终止。
for 与 while 的选择原则
| 场景 | 推荐 | 理由 |
|---|---|---|
| 遍历已有序列 | for | 更简洁,无需手动管理索引 |
| 已知迭代次数 | for + range() | 清晰明确 |
| 迭代次数未知 | while | 按条件决定何时停止 |
| 持续等待用户输入 | while True + break | 灵活控制退出时机 |
经验法则:能用 for 就用 for。for 循环更不易出现死循环,代码也更清晰。
实战:猜数字游戏
import random
target = random.randint(10, 99)
attempt = 0
print("猜一个两位数(10-99)")
while True:
guess = int(input("你的答案:"))
attempt += 1
if guess < target:
print("偏小")
elif guess > target:
print("偏大")
else:
print(f"正确!答案是 {target},你用了 {attempt} 次")
break
break 和 continue:精确控制循环流程
break:立即终止循环
# 在序列中找到第一个负数
readings = [12, 7, 3, -5, 8, 2]
for val in readings:
if val < 0:
print(f"检测到异常值:{val}")
break
# 检测到异常值:-5
continue:跳过当前迭代
# 只处理有效数据,跳过空值
entries = ["data_a", "", "data_b", "", "data_c"]
for entry in entries:
if entry == "":
continue
print(f"处理:{entry}")
# 处理:data_a
# 处理:data_b
# 处理:data_c
区分 break 与 continue
print("break 效果:")
for n in range(1, 6):
if n == 3:
break
print(n, end=" ")
# 1 2
print("\ncontinue 效果:")
for n in range(1, 6):
if n == 3:
continue
print(n, end=" ")
# 1 2 4 5
break:彻底终止整个循环continue:跳过本次迭代,进入下一次
**设计建议:**尽量减少 break 和 continue 的使用。多数场景可以通过调整循环条件来替代,从而使逻辑更清晰。
for…else 结构
Python 独有的语法:当 for 循环正常结束(未被 break 中断)时,执行 else 块:
candidate = 29
for divisor in range(2, int(candidate ** 0.5) + 1):
if candidate % divisor == 0:
print(f"{candidate} 不是素数,{candidate} = {divisor} x {candidate // divisor}")
break
else:
print(f"{candidate} 是素数")
# 29 是素数
循环嵌套
处理二维数据时,常需要循环嵌套:
# 生成乘法口诀表
for row in range(1, 10):
for col in range(1, row + 1):
print(f"{col}*{row}={row * col:2d}", end=" ")
print()
# 查找 200 以内的所有素数
for candidate in range(2, 201):
is_prime = True
for divisor in range(2, int(candidate ** 0.5) + 1):
if candidate % divisor == 0:
is_prime = False
break
if is_prime:
print(candidate, end=" ")
列表推导式
列表推导式是 Python 最具特色的语法之一,能将循环和条件压缩为一行表达式。
基本形式
# 传统循环
cubes = []
for v in range(1, 8):
cubes.append(v ** 3)
print(cubes) # [1, 8, 27, 64, 125, 216, 343]
# 列表推导式(等价)
cubes = [v ** 3 for v in range(1, 8)]
print(cubes) # [1, 8, 27, 64, 125, 216, 343]
带条件过滤
# 只保留能被 3 整除的数
multiples = [n for n in range(1, 31) if n % 3 == 0]
print(multiples) # [3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
# 过滤掉零和负数
measurements = [-2, 0, 5, -1, 8, 3]
valid = [m for m in measurements if m > 0]
print(valid) # [5, 8, 3]
更多应用
# 批量清洗数据
raw_tags = [" api ", " backend ", " deploy "]
clean_tags = [t.strip() for t in raw_tags]
print(clean_tags) # ['api', 'backend', 'deploy']
# 转换大小写
commands = ["get", "post", "put", "delete"]
upper_commands = [cmd.upper() for cmd in commands]
print(upper_commands) # ['GET', 'POST', 'PUT', 'DELETE']
# 构建键值对列表
mappings = [(n, n ** 2) for n in range(7)]
print(mappings) # [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36)]
# 展平嵌套列表
grid = [[1, 2], [3, 4], [5, 6]]
flat = [cell for row in grid for cell in row]
print(flat) # [1, 2, 3, 4, 5, 6]
**可读性原则:**如果推导式逻辑过于复杂,一行难以理解,就改写为普通循环。
字典推导式与集合推导式
# 字典推导式
power_map = {n: 2 ** n for n in range(8)}
print(power_map)
# {0: 1, 1: 2, 2: 4, 3: 8, 4: 16, 5: 32, 6: 64, 7: 128}
# 集合推导式(自动去重)
sentence = "to be or not to be"
unique_words = {w for w in sentence.split() if len(w) > 1}
print(unique_words) # {'to', 'be', 'or', 'not'}
补充:常见的循环应用场景
统计计算
# 计算列表的平均值
values = [85, 92, 78, 96, 64, 73, 88]
total = 0
for val in values:
total += val
average = total / len(values)
print(f"平均值:{average:.1f}") # 平均值:82.3
查找最值
# 手动查找最大值(理解原理)
temperatures = [23.5, 19.2, 27.8, 21.0, 30.1, 18.5]
highest = temperatures[0]
for temp in temperatures:
if temp > highest:
highest = temp
print(f"最高温度:{highest}") # 最高温度:30.1
字符串逐字符处理
# 统计字符串中大写字母的数量
text = "Hello World From Python"
uppercase_count = 0
for ch in text:
if ch.isupper():
uppercase_count += 1
print(f"大写字母数量:{uppercase_count}") # 4
累积构建字符串
# 将数字列表转换为以逗号分隔的字符串
ids = [101, 205, 307, 412]
parts = []
for id_val in ids:
parts.append(str(id_val))
csv_output = ",".join(parts)
print(csv_output) # 101,205,307,412
综合实战:商品价格分析器
catalog = []
print("====== 商品价格分析器 ======")
print("逐条录入商品信息,输入 done 结束\n")
while True:
product_name = input("商品名称(输入 done 结束):")
if product_name == "done":
break
unit_price = float(input(f"{product_name} 的单价:"))
catalog.append({"product": product_name, "price": unit_price})
print(f"已录入:{product_name} - {unit_price} 元\n")
if len(catalog) == 0:
print("未录入任何商品")
else:
prices = [item["price"] for item in catalog]
total_val = sum(prices)
avg_val = total_val / len(prices)
top_price = max(prices)
low_price = min(prices)
print("\n====== 分析报告 ======")
print(f"商品总数:{len(catalog)}")
print(f"均价:{avg_val:.2f} 元")
print(f"最高价:{top_price} 元")
print(f"最低价:{low_price} 元")
premium = len([p for p in prices if p >= 500])
mid_range = len([p for p in prices if 100 <= p < 500])
budget = len([p for p in prices if p < 100])
print(f"\n高端(>= 500):{premium} 件")
print(f"中端(100-499):{mid_range} 件")
print(f"经济(< 100):{budget} 件")
print("\n------ 明细 ------")
for seq, item in enumerate(catalog):
tier = "高端" if item["price"] >= 500 else \
"中端" if item["price"] >= 100 else "经济"
print(f"{seq + 1}. {item['product']:10} {item['price']:>10.2f} 元 [{tier}]")
本章回顾
| 要点 | 内容 |
|---|---|
| if / elif / else | 条件分支,根据条件执行不同路径 |
| 比较运算符 | == != > < >= <= |
| 逻辑运算符 | and or not |
| for 循环 | 遍历序列中的每个元素 |
| while 循环 | 条件为 True 时持续执行 |
| range() | 生成整数序列 |
| break | 终止整个循环 |
| continue | 跳过本次迭代 |
| 列表推导式 | [expr for var in seq if cond] |
补充:while True 的常用模式
在实际开发中,while True 配合 break 是处理”持续接收输入直到满足退出条件”的标准模式:
# 模式一:输入验证循环
while True:
raw = input("请输入一个正整数:")
if raw.isdigit() and int(raw) > 0:
number = int(raw)
break
print("输入无效,请重新输入")
print(f"你输入的正整数是:{number}")
# 模式二:菜单交互循环
while True:
print("\n1. 查看状态")
print("2. 执行操作")
print("3. 退出")
action = input("选择:")
if action == "1":
print("当前状态:正常")
elif action == "2":
print("操作已执行")
elif action == "3":
print("再见")
break
else:
print("无效选择")
这两种模式在后续章节的实战项目中会频繁出现。
补充:赋值运算符速记
在循环中经常需要对变量进行累加或累乘操作,Python 提供了简写形式:
total = 0
total += 10 # 等价于 total = total + 10
total -= 3 # 等价于 total = total - 3
total *= 2 # 等价于 total = total * 2
total //= 4 # 等价于 total = total // 4
# 在循环中的典型应用
product = 1
for factor in [2, 3, 5, 7]:
product *= factor
print(product) # 210
实践任务
- 编写程序判断输入的年份是否为闰年(能被 4 整除且不能被 100 整除,或能被 400 整除)
- 用 for 循环生成乘法口诀表
- 实现猜数字游戏,限制最多尝试 8 次
- 用列表推导式生成 1 到 50 中所有能被 7 整除的数
- 编写程序判断输入的正整数是否为素数
- 用 while 循环实现一个简单的命令行菜单系统
下一章,我们将从一个重复性工作场景出发,学习函数——把常用的操作封装为可复用的代码单元。
购买课程解锁全部内容
零基础到独立开发:Python 自动化与 Web 实战
¥29.90