Python控制流:条件与循环的艺术
控制流是编程的决策中枢,它让程序从简单的指令序列转变为智能的逻辑系统。掌握条件与循环,你就掌握了让代码"思考"和"重复工作"的能力。
前言:从顺序执行到智能决策
在前面的章节中,我们学习了Python的基础语法和数据类型。你可能会有一个疑问:"如果...那么..."这样的逻辑如何在代码中表达? 或者 "如何让代码重复执行某个任务直到满足条件?"
这就是控制流要解决的问题。控制流决定了代码的执行顺序,让程序能够根据不同的条件做出不同的决策,或者重复执行某些操作直到满足特定条件。
让我用一个生活中的例子来解释:假设你要根据天气决定穿什么衣服:
- 顺序执行:就是不管天气如何,都穿同一套衣服
- 条件判断:如果下雨,穿雨衣;如果晴天,穿T恤;如果下雪,穿羽绒服
- 循环:每天都检查天气预报并决定穿什么,直到冬天结束
在本章中,我们将深入学习Python中的条件语句和循环语句,让你的代码从"机械执行"变为"智能决策"。
4.1 条件语句:if、elif、else
条件语句是编程中的决策者,它让程序能够根据不同的条件执行不同的代码块。
基础语法:if语句
# 最简单的if语句
温度 = 28
if 温度 > 30:
print("天气很热,建议穿短袖")
print("记得多喝水!")
# 注意:if语句后面的冒号和缩进!
# Python使用缩进来表示代码块,通常使用4个空格
# 实际应用:判断用户年龄
def 检查年龄(年龄):
"""根据年龄给出不同的建议"""
if 年龄 < 0:
print("年龄不能为负数!")
elif 年龄 < 18:
print("您是未成年人")
elif 年龄 < 60:
print("您是成年人")
else:
print("您是老年人")
print("检查完成")
# 测试
测试年龄 = [15, 25, 65, -5]
for 年龄 in 测试年龄:
print(f"\n年龄: {年龄}")
检查年龄(年龄)完整的if-elif-else结构
def 计算成绩等级(分数):
"""
根据分数计算成绩等级
90-100: A
80-89: B
70-79: C
60-69: D
0-59: F
"""
if 分数 < 0 or 分数 > 100:
return "无效分数"
elif 分数 >= 90:
return "A"
elif 分数 >= 80:
return "B"
elif 分数 >= 70:
return "C"
elif 分数 >= 60:
return "D"
else:
return "F"
# 测试成绩等级
print("成绩等级测试:")
测试分数 = [95, 85, 75, 65, 55, 105, -5]
for 分数 in 测试分数:
等级 = 计算成绩等级(分数)
print(f" 分数{分数:3d}: {等级}")
# 复杂条件判断
def 判断三角形类型(边1, 边2, 边3):
"""判断三角形的类型"""
# 检查是否能构成三角形
if 边1 <= 0 or 边2 <= 0 or 边3 <= 0:
return "边长必须为正数"
if (边1 + 边2 <= 边3) or (边1 + 边3 <= 边2) or (边2 + 边3 <= 边1):
return "不能构成三角形(两边之和必须大于第三边)"
# 判断三角形类型
if 边1 == 边2 == 边3:
return "等边三角形"
elif 边1 == 边2 or 边1 == 边3 or 边2 == 边3:
return "等腰三角形"
elif (边1**2 + 边2**2 == 边3**2 or
边1**2 + 边3**2 == 边2**2 or
边2**2 + 边3**2 == 边1**2):
return "直角三角形"
else:
return "普通三角形"
# 测试三角形判断
print("\n三角形类型判断:")
测试三角形 = [
(3, 4, 5), # 直角三角形
(5, 5, 5), # 等边三角形
(5, 5, 7), # 等腰三角形
(2, 3, 4), # 普通三角形
(1, 2, 3), # 不能构成三角形
(-1, 2, 3), # 边长错误
]
for 边1, 边2, 边3 in 测试三角形:
类型 = 判断三角形类型(边1, 边2, 边3)
print(f" 边长({边1}, {边2}, {边3}): {类型}")使用逻辑运算符组合条件
# 检查用户名和密码
def 验证登录(用户名, 密码):
"""验证用户登录信息"""
# 定义有效用户(在实际应用中,这些信息通常来自数据库)
有效用户 = {
"admin": "admin123",
"user1": "password1",
"user2": "password2"
}
# 组合条件判断
if not 用户名: # 用户名为空
return False, "用户名不能为空"
elif not 密码: # 密码为空
return False, "密码不能为空"
elif 用户名 not in 有效用户: # 用户名不存在
return False, "用户名不存在"
elif 有效用户[用户名] != 密码: # 密码错误
return False, "密码错误"
else: # 所有条件都满足
return True, "登录成功"
# 测试登录验证
print("\n登录验证测试:")
测试用例 = [
("", "password"), # 用户名为空
("admin", ""), # 密码为空
("unknown", "password"), # 用户名不存在
("admin", "wrong"), # 密码错误
("admin", "admin123"), # 正确
("user1", "password1"), # 正确
]
for 用户名, 密码 in 测试用例:
成功, 消息 = 验证登录(用户名, 密码)
状态 = "✅" if 成功 else "❌"
print(f" {状态} 用户名: '{用户名}', 密码: '{密码}' -> {消息}")
# 复杂业务逻辑:订单处理
def 处理订单(订单金额, 用户类型, 优惠码=None):
"""处理订单,计算最终价格"""
折扣 = 0
运费 = 0
# 根据用户类型确定折扣
if 用户类型 == "VIP":
折扣 = 0.2 # 8折
运费 = 0 # VIP免运费
elif 用户类型 == "高级会员":
折扣 = 0.1 # 9折
运费 = 5 # 5元运费
else: # 普通用户
折扣 = 0 # 无折扣
运费 = 10 # 10元运费
# 检查优惠码
if 优惠码 == "SAVE10":
折扣 = max(折扣, 0.1) # 取最大折扣
elif 优惠码 == "FREESHIP":
运费 = 0 # 免运费
# 计算最终价格
折扣金额 = 订单金额 * 折扣
折后价格 = 订单金额 - 折扣金额
最终价格 = 折后价格 + 运费
# 满减活动(不与折扣叠加)
if 订单金额 >= 200 and 优惠码 != "SAVE10": # 不与SAVE10叠加
满减 = 30
最终价格 = min(最终价格, 订单金额 - 满减 + 运费)
return 最终价格, 折扣金额, 运费
# 测试订单处理
print("\n订单处理测试:")
订单测试 = [
(150, "普通用户", None),
(150, "普通用户", "FREESHIP"),
(150, "高级会员", None),
(150, "VIP", None),
(250, "普通用户", None),
(250, "普通用户", "SAVE10"),
]
for 金额, 类型, 优惠 in 订单测试:
最终价格, 折扣金额, 运费 = 处理订单(金额, 类型, 优惠)
print(f" 订单: ¥{金额}, 用户: {类型}, 优惠码: {优惠 or '无'}")
print(f" 折扣: ¥{折扣金额:.2f}, 运费: ¥{运费}, 最终价格: ¥{最终价格:.2f}")4.2 嵌套条件语句
嵌套条件语句是指在一个条件语句的代码块中包含另一个条件语句。这允许我们处理更复杂的决策逻辑。
基础嵌套示例
# 简单的嵌套if语句
def 检查访问权限(用户角色, 资源类型, 操作类型):
"""检查用户是否有权限执行操作"""
if 用户角色 == "管理员":
# 管理员有所有权限
return True, "管理员拥有所有权限"
elif 用户角色 == "编辑":
# 编辑有部分权限
if 资源类型 == "文章":
if 操作类型 in ["读取", "编辑", "发布"]:
return True, "编辑可以操作文章"
else:
return False, "编辑不能执行此操作"
elif 资源类型 == "评论":
if 操作类型 in ["读取", "审核"]:
return True, "编辑可以审核评论"
else:
return False, "编辑不能执行此操作"
else:
return False, "编辑不能操作此资源类型"
elif 用户角色 == "读者":
# 读者只有读取权限
if 操作类型 == "读取":
return True, "读者可以读取"
else:
return False, "读者只能读取"
else:
return False, "未知用户角色"
# 测试权限检查
print("访问权限检查:")
测试用例 = [
("管理员", "文章", "删除"),
("编辑", "文章", "编辑"),
("编辑", "文章", "删除"),
("编辑", "评论", "审核"),
("读者", "文章", "读取"),
("读者", "文章", "编辑"),
("访客", "文章", "读取"),
]
for 角色, 资源, 操作 in 测试用例:
允许, 消息 = 检查访问权限(角色, 资源, 操作)
状态 = "✅ 允许" if 允许 else "❌ 拒绝"
print(f" {状态}: {角色} {操作} {资源} -> {消息}")多层嵌套与扁平化
# 多层嵌套示例(可能变得难以阅读)
def 多层嵌套示例(成绩, 出勤率, 作业完成度):
"""多层嵌套的条件判断"""
if 成绩 >= 60:
if 出勤率 >= 80:
if 作业完成度 >= 70:
return "通过,表现良好"
else:
if 作业完成度 >= 50:
return "通过,但作业需要改进"
else:
return "条件通过,作业严重不足"
else:
return "成绩合格但出勤率不足"
else:
if 出勤率 >= 90:
if 作业完成度 >= 90:
return "成绩不合格,但出勤和作业优秀,给予补考机会"
else:
return "成绩不合格"
else:
return "成绩不合格且出勤率不足"
# 扁平化嵌套条件
def 扁平化示例(成绩, 出勤率, 作业完成度):
"""使用扁平化的条件判断"""
# 提前返回模式(early return)
if 成绩 < 60 and 出勤率 >= 90 and 作业完成度 >= 90:
return "成绩不合格,但出勤和作业优秀,给予补考机会"
if 成绩 < 60:
return "成绩不合格" if 出勤率 < 90 else "成绩不合格"
if 出勤率 < 80:
return "成绩合格但出勤率不足"
if 作业完成度 < 50:
return "条件通过,作业严重不足"
elif 作业完成度 < 70:
return "通过,但作业需要改进"
else:
return "通过,表现良好"
# 比较两种方式
print("\n嵌套条件 vs 扁平化条件:")
测试数据 = [
(85, 95, 90), # 通过,表现良好
(70, 75, 80), # 成绩合格但出勤率不足
(65, 85, 60), # 通过,但作业需要改进
(55, 95, 95), # 补考机会
(50, 80, 80), # 成绩不合格
]
for 成绩, 出勤率, 作业完成度 in 测试数据:
结果1 = 多层嵌套示例(成绩, 出勤率, 作业完成度)
结果2 = 扁平化示例(成绩, 出勤率, 作业完成度)
print(f" 成绩{成绩}, 出勤{出勤率}%, 作业{作业完成度}%:")
print(f" 嵌套: {结果1}")
print(f" 扁平: {结果2}")
print(f" 结果相同: {结果1 == 结果2}")实际应用:游戏角色状态判断
def 判断游戏角色状态(生命值, 魔法值, 状态列表):
"""
判断游戏角色的当前状态
参数:
生命值: 0-100
魔法值: 0-100
状态列表: 包含当前状态的列表,如 ["中毒", "眩晕"]
返回:
str: 角色状态描述
"""
状态描述 = []
# 生命值判断
if 生命值 <= 0:
状态描述.append("死亡")
elif 生命值 <= 10:
状态描述.append("濒死")
elif 生命值 <= 30:
状态描述.append("重伤")
elif 生命值 <= 50:
状态描述.append("受伤")
elif 生命值 < 100:
状态描述.append("健康")
else:
状态描述.append("满血")
# 魔法值判断
if 魔法值 <= 0:
状态描述.append("魔力枯竭")
elif 魔法值 <= 20:
状态描述.append("低魔力")
elif 魔法值 < 100:
状态描述.append("魔力充足")
else:
状态描述.append("魔力全满")
# 特殊状态判断
特殊状态映射 = {
"中毒": "正在持续掉血",
"眩晕": "无法行动",
"燃烧": "受到火焰伤害",
"冰冻": "移动速度降低",
"沉默": "无法使用魔法",
"治疗": "正在恢复生命值",
}
for 状态 in 状态列表:
if 状态 in 特殊状态映射:
状态描述.append(特殊状态映射[状态])
else:
状态描述.append(f"未知状态: {状态}")
# 综合判断
if "死亡" in 状态描述:
return "角色已死亡"
elif "濒死" in 状态描述:
return "角色濒临死亡,需要紧急治疗!"
elif "魔力枯竭" in 状态描述 and "低魔力" in 状态描述:
return "角色魔力严重不足,建议休息恢复"
else:
return f"角色状态: {', '.join(状态描述)}"
# 测试游戏角色状态
print("\n游戏角色状态判断:")
测试角色 = [
(100, 100, []), # 满状态
(75, 30, []), # 健康,魔力充足
(8, 50, ["中毒"]), # 濒死,中毒
(45, 5, ["燃烧", "沉默"]), # 受伤,魔力枯竭,特殊状态
(0, 100, []), # 死亡
(60, 80, ["治疗", "冰冻"]), # 受伤,治疗中
]
for 生命值, 魔法值, 状态 in 测试角色:
状态描述 = 判断游戏角色状态(生命值, 魔法值, 状态)
print(f" 生命{生命值:3d}, 魔法{魔法值:3d}, 状态{状态}:")
print(f" {状态描述}")4.3 循环语句:while循环
while循环在条件为真时重复执行代码块。它适用于不知道具体循环次数,但知道循环终止条件的情况。
基础while循环
# 基本while循环
def 倒计时(秒数):
"""倒计时函数"""
print(f"开始倒计时: {秒数}秒")
当前秒数 = 秒数
while 当前秒数 > 0:
print(f" {当前秒数}...")
当前秒数 -= 1 # 重要:一定要改变循环条件,否则会无限循环!
print("时间到!")
# 执行倒计时
print("倒计时示例:")
倒计时(5)
# 用户输入验证
def 获取有效年龄():
"""获取有效的用户年龄"""
while True: # 无限循环,直到得到有效输入
输入 = input("请输入您的年龄(0-120): ")
try:
年龄 = int(输入)
if 年龄 < 0:
print("年龄不能为负数!")
elif 年龄 > 120:
print("年龄不能超过120岁!")
else:
print(f"您的年龄是: {年龄}岁")
return 年龄 # 返回有效年龄并退出循环
except ValueError:
print("请输入有效的数字!")
# 注意:这里我们注释掉实际调用,以免阻塞程序执行
# print("\n年龄输入示例:")
# 年龄 = 获取有效年龄()
# 计算阶乘
def 计算阶乘(n):
"""计算n的阶乘(n! = n * (n-1) * ... * 1)"""
if n < 0:
return "负数没有阶乘"
结果 = 1
当前数 = n
while 当前数 > 1:
结果 *= 当前数
当前数 -= 1
return 结果
print("\n阶乘计算:")
for i in range(1, 11):
阶乘 = 计算阶乘(i)
print(f" {i}! = {阶乘}")while循环的实际应用
# 模拟银行取款
def 银行取款模拟():
"""模拟银行取款过程"""
余额 = 10000.0 # 初始余额
print(f"初始余额: ¥{余额:.2f}")
while True:
print("\n" + "="*40)
print("银行取款系统")
print("="*40)
print("1. 查询余额")
print("2. 取款")
print("3. 退出")
选择 = input("请选择操作(1-3): ")
if 选择 == "1":
print(f"当前余额: ¥{余额:.2f}")
elif 选择 == "2":
金额 = input("请输入取款金额: ")
try:
取款金额 = float(金额)
if 取款金额 <= 0:
print("取款金额必须大于0!")
elif 取款金额 > 余额:
print(f"余额不足!当前余额: ¥{余额:.2f}")
else:
余额 -= 取款金额
print(f"取款成功: ¥{取款金额:.2f}")
print(f"剩余余额: ¥{余额:.2f}")
if 余额 == 0:
print("您的账户余额已为0,无法继续取款")
break
except ValueError:
print("请输入有效的金额!")
elif 选择 == "3":
print("感谢使用,再见!")
break
else:
print("无效选择,请重新输入!")
return 余额
# 注意:这里我们注释掉实际调用,以免阻塞程序执行
# print("\n银行取款模拟:")
# 最终余额 = 银行取款模拟()
# 猜数字游戏
def 猜数字游戏():
"""经典的猜数字游戏"""
import random
秘密数字 = random.randint(1, 100)
最大尝试次数 = 10
尝试次数 = 0
print("猜数字游戏开始!")
print(f"我已经想好了一个1-100之间的数字,你有{最大尝试次数}次机会猜中它。")
while 尝试次数 < 最大尝试次数:
剩余次数 = 最大尝试次数 - 尝试次数
print(f"\n你还剩{剩余次数}次机会")
try:
猜测 = int(input("请输入你的猜测(1-100): "))
if 猜测 < 1 or 猜测 > 100:
print("请输入1-100之间的数字!")
continue
尝试次数 += 1
if 猜测 < 秘密数字:
print("太小了!")
elif 猜测 > 秘密数字:
print("太大了!")
else:
print(f"恭喜你!你在第{尝试次数}次猜中了数字{秘密数字}!")
return 尝试次数
except ValueError:
print("请输入有效的数字!")
print(f"\n游戏结束!你没有在{最大尝试次数}次内猜中数字。")
print(f"正确的数字是: {秘密数字}")
return 尝试次数
# 注意:这里我们注释掉实际调用,以免阻塞程序执行
# print("\n猜数字游戏:")
# 最终尝试次数 = 猜数字游戏()
# 模拟数据加载进度
def 显示加载进度(总项目数):
"""模拟数据加载进度"""
print("开始加载数据...")
已加载 = 0
while 已加载 < 总项目数:
# 模拟加载过程
import time
time.sleep(0.1) # 模拟加载延迟
已加载 += 1
进度百分比 = (已加载 / 总项目数) * 100
# 创建进度条
进度条长度 = 30
已完成长度 = int(进度百分比 / 100 * 进度条长度)
进度条 = "[" + "=" * 已完成长度 + " " * (进度条长度 - 已完成长度) + "]"
# 显示进度
print(f"\r进度: {进度条} {进度百分比:.1f}% ({已加载}/{总项目数})", end="")
print("\n数据加载完成!")
# 测试进度显示
print("\n数据加载进度模拟:")
显示加载进度(100)4.4 循环语句:for循环与迭代
for循环用于遍历序列(如列表、元组、字符串)或其他可迭代对象。它是Python中最常用的循环结构。
基础for循环
# 遍历列表
水果列表 = ["苹果", "香蕉", "橙子", "葡萄", "芒果"]
print("遍历水果列表:")
for 水果 in 水果列表:
print(f" 我喜欢吃{水果}")
# 遍历字符串
文本 = "Python编程"
print("\n遍历字符串:")
for 字符 in 文本:
print(f" 字符: {字符}")
# 遍历字典
学生信息 = {
"姓名": "张三",
"年龄": 20,
"专业": "计算机科学",
"成绩": {"数学": 90, "英语": 85}
}
print("\n遍历字典:")
for 键 in 学生信息:
print(f" {键}: {学生信息[键]}")
print("\n遍历字典的键值对:")
for 键, 值 in 学生信息.items():
print(f" {键}: {值}")
# 使用range()函数
print("\n使用range()函数:")
print("range(5):", list(range(5))) # 0, 1, 2, 3, 4
print("range(2, 8):", list(range(2, 8))) # 2, 3, 4, 5, 6, 7
print("range(1, 10, 2):", list(range(1, 10, 2))) # 1, 3, 5, 7, 9
print("\n使用for循环和range:")
for i in range(5):
print(f" 第{i+1}次循环")for循环的实际应用
# 统计列表信息
def 分析数据(数据列表):
"""分析数据列表的统计信息"""
统计结果 = {
"总数": 0,
"总和": 0,
"最大值": float('-inf'),
"最小值": float('inf'),
"正数个数": 0,
"负数个数": 0,
"偶数个数": 0,
"奇数个数": 0,
}
for 数据 in 数据列表:
统计结果["总数"] += 1
统计结果["总和"] += 数据
if 数据 > 统计结果["最大值"]:
统计结果["最大值"] = 数据
if 数据 < 统计结果["最小值"]:
统计结果["最小值"] = 数据
if 数据 > 0:
统计结果["正数个数"] += 1
elif 数据 < 0:
统计结果["负数个数"] += 1
if 数据 % 2 == 0:
统计结果["偶数个数"] += 1
else:
统计结果["奇数个数"] += 1
# 计算平均值
统计结果["平均值"] = 统计结果["总和"] / 统计结果["总数"] if 统计结果["总数"] > 0 else 0
return 统计结果
# 测试数据分析
测试数据 = [12, -5, 8, 0, 15, -3, 7, 20, -1, 10]
分析结果 = 分析数据(测试数据)
print("数据分析结果:")
print(f" 原始数据: {测试数据}")
for 指标, 值 in 分析结果.items():
if isinstance(值, float):
print(f" {指标}: {值:.2f}")
else:
print(f" {指标}: {值}")
# 生成乘法表
def 生成乘法表(最大乘数=9):
"""生成乘法表"""
print("乘法表:")
# 表头
print(" ", end="")
for i in range(1, 最大乘数 + 1):
print(f"{i:4d}", end="")
print()
print(" " + "----" * 最大乘数)
# 表格内容
for i in range(1, 最大乘数 + 1):
print(f"{i:2d}|", end="")
for j in range(1, 最大乘数 + 1):
print(f"{i*j:4d}", end="")
print()
# 生成9x9乘法表
print("\n9x9乘法表:")
生成乘法表(9)
# 处理嵌套数据结构
def 扁平化嵌套列表(嵌套列表):
"""将嵌套列表扁平化为单层列表"""
结果 = []
for 元素 in 嵌套列表:
if isinstance(元素, list):
# 递归处理嵌套列表
结果.extend(扁平化嵌套列表(元素))
else:
结果.append(元素)
return 结果
# 测试扁平化
嵌套列表 = [1, [2, 3, [4, 5]], 6, [7, [8, 9]]]
扁平化结果 = 扁平化嵌套列表(嵌套列表)
print(f"\n嵌套列表: {嵌套列表}")
print(f"扁平化结果: {扁平化结果}")
# 使用enumerate()获取索引和值
def 处理学生列表(学生列表):
"""处理学生列表,添加序号"""
print("\n学生列表(带序号):")
for 序号, 学生 in enumerate(学生列表, start=1):
print(f" {序号}. {学生}")
# 测试enumerate
学生列表 = ["张三", "李四", "王五", "赵六"]
处理学生列表(学生列表)
# 使用zip()同时遍历多个序列
def 合并学生成绩(学生列表, 成绩列表):
"""合并学生和成绩信息"""
print("\n学生成绩表:")
for 学生, 成绩 in zip(学生列表, 成绩列表):
print(f" {学生}: {成绩}分")
# 测试zip
成绩列表 = [85, 92, 78, 88]
合并学生成绩(学生列表, 成绩列表)4.5 循环控制:break、continue、pass
循环控制语句允许我们更精细地控制循环的执行流程。
break语句:提前退出循环
# break示例:在列表中查找元素
def 查找元素(列表, 目标):
"""在列表中查找元素,找到后立即停止"""
print(f"在列表中查找元素 {目标}")
for i, 元素 in enumerate(列表):
print(f" 检查第{i+1}个元素: {元素}")
if 元素 == 目标:
print(f" 找到目标元素 {目标} 在位置 {i}")
break # 找到后立即退出循环
else:
# 注意:这里的else属于for循环,当循环正常完成(没有被break中断)时执行
print(f" 未找到元素 {目标}")
return i if 元素 == 目标 else -1
# 测试查找
数字列表 = [3, 7, 2, 9, 5, 1, 8]
位置 = 查找元素(数字列表, 5)
print(f"元素5的位置: {位置}")
位置 = 查找元素(数字列表, 10)
print(f"元素10的位置: {位置}")
# 密码验证(最多尝试3次)
def 密码验证():
"""密码验证,最多尝试3次"""
正确密码 = "Python123"
最大尝试次数 = 3
for 尝试次数 in range(1, 最大尝试次数 + 1):
密码 = input(f"请输入密码(第{尝试次数}次尝试): ")
if 密码 == 正确密码:
print("密码正确!登录成功。")
break
else:
print("密码错误!")
if 尝试次数 == 最大尝试次数:
print("已达到最大尝试次数,账户已被锁定。")
else:
print(f"还剩{最大尝试次数 - 尝试次数}次尝试机会。")
else:
# 如果循环正常结束(即break没有被执行)
print("验证失败。")
# 注意:这里我们注释掉实际调用
# print("\n密码验证示例:")
# 密码验证()
# 搜索第一个满足条件的元素
def 查找第一个满足条件的数字(数字列表, 条件函数):
"""查找第一个满足条件的数字"""
for 数字 in 数字列表:
if 条件函数(数字):
print(f"找到第一个满足条件的数字: {数字}")
return 数字
print("没有找到满足条件的数字")
return None
# 测试
def 是质数(n):
"""判断是否为质数(简化版)"""
if n < 2:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True
数字列表 = [4, 6, 8, 9, 10, 11, 12, 13]
结果 = 查找第一个满足条件的数字(数字列表, 是质数)
print(f"第一个质数是: {结果}")continue语句:跳过当前迭代
# continue示例:处理数据时跳过无效值
def 处理数据列表(数据列表):
"""处理数据列表,跳过无效值"""
print("处理数据列表(跳过非正数):")
有效数据 = []
for 数据 in 数据列表:
if 数据 <= 0:
print(f" 跳过无效数据: {数据}")
continue # 跳过当前迭代
# 处理有效数据
处理结果 = 数据 * 2 # 示例处理:乘以2
有效数据.append(处理结果)
print(f" 处理数据 {数据} -> {处理结果}")
print(f"有效数据结果: {有效数据}")
return 有效数据
# 测试
测试数据 = [1, -2, 3, 0, 5, -1, 7]
处理结果 = 处理数据列表(测试数据)
# 统计文本中的元音字母(跳过非字母字符)
def 统计元音字母(文本):
"""统计文本中的元音字母"""
元音字母 = {'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'}
统计结果 = {元音: 0 for 元音 in 'aeiou'}
print(f"统计文本中的元音字母: {文本}")
for 字符 in 文本:
if not 字符.isalpha():
continue # 跳过非字母字符
小写字符 = 字符.lower()
if 小写字符 in 元音字母:
统计结果[小写字符] += 1
print(f" 找到元音字母: {字符}")
return 统计结果
# 测试元音统计
文本 = "Hello, Python Programming! It's awesome."
元音统计 = 统计元音字母(文本)
print("元音字母统计:")
for 元音, 次数 in sorted(元音统计.items()):
print(f" {元音}: {次数}次")
# 处理CSV数据,跳过空行和注释行
def 处理CSV数据(CSV文本):
"""处理CSV数据,跳过空行和注释行"""
print("处理CSV数据:")
行列表 = CSV文本.strip().split('\n')
数据行 = []
for 行号, 行内容 in enumerate(行列表, 1):
行内容 = 行内容.strip()
# 跳过空行
if not 行内容:
print(f" 第{行号}行: 空行,跳过")
continue
# 跳过注释行(以#开头)
if 行内容.startswith('#'):
print(f" 第{行号}行: 注释行,跳过")
continue
# 处理数据行
字段 = 行内容.split(',')
数据行.append(字段)
print(f" 第{行号}行: 数据行 -> {字段}")
return 数据行
# 测试CSV处理
CSV示例 = """
# 学生信息表
姓名,年龄,成绩
张三,20,85
李四,22,92
# 空行测试
王五,21,78
# 这是注释
赵六,23,88
"""
CSV数据 = 处理CSV数据(CSV示例)
print(f"处理后的数据行数: {len(CSV数据)}")pass语句:占位符
# pass示例:占位符
def 待实现的功能():
"""这个功能还没有实现"""
pass # TODO: 实现这个功能
def 处理用户输入(用户输入):
"""处理用户输入(简化示例)"""
if 用户输入 == "1":
print("执行功能1")
elif 用户输入 == "2":
print("执行功能2")
elif 用户输入 == "3":
# 功能3还没有实现,先用pass占位
pass # TODO: 实现功能3
else:
print("无效输入")
# 空类定义
class 待实现的类:
"""这个类还没有实现"""
pass # TODO: 实现这个类
# 循环中的pass
def 处理数字列表(数字列表):
"""处理数字列表,暂时跳过偶数"""
print("处理数字列表(暂时跳过偶数):")
for 数字 in 数字列表:
if 数字 % 2 == 0:
# 暂时不处理偶数
pass # TODO: 添加偶数处理逻辑
else:
# 处理奇数
print(f" 处理奇数: {数字}")
# 测试
数字列表 = [1, 2, 3, 4, 5, 6]
处理数字列表(数字列表)
# 对比:pass vs continue
def pass_vs_continue示例():
"""展示pass和continue的区别"""
print("\npass vs continue 对比:")
数字列表 = [1, 2, 3, 4, 5]
print("使用pass(什么也不做,继续执行):")
for 数字 in 数字列表:
if 数字 % 2 == 0:
pass # 什么也不做,继续执行后面的代码
print(f" 处理数字: {数字}")
print("\n使用continue(跳过后续代码,继续下一次迭代):")
for 数字 in 数字列表:
if 数字 % 2 == 0:
continue # 跳过后续代码,继续下一次迭代
print(f" 处理数字: {数字}")循环控制综合示例
def 数据分析工具(数据列表):
"""
数据分析工具
功能:
1. 跳过无效数据(None或非数字)
2. 遇到特定的"停止符"时停止处理
3. 统计处理的数据信息
"""
print("开始数据分析...")
统计信息 = {
"总数据量": 0,
"有效数据量": 0,
"无效数据量": 0,
"处理的数据": [],
"遇到停止符": False,
"数据总和": 0,
}
for 数据 in 数据列表:
统计信息["总数据量"] += 1
# 检查是否为停止符
if 数据 == "STOP":
print("遇到停止符,停止处理")
统计信息["遇到停止符"] = True
break
# 检查数据有效性
if 数据 is None:
print(f" 数据{统计信息['总数据量']}: None,跳过")
统计信息["无效数据量"] += 1
continue
if not isinstance(数据, (int, float)):
print(f" 数据{统计信息['总数据量']}: {数据}(非数字),跳过")
统计信息["无效数据量"] += 1
continue
# 处理有效数据
统计信息["有效数据量"] += 1
统计信息["数据总和"] += 数据
统计信息["处理的数据"].append(数据)
print(f" 处理数据{统计信息['总数据量']}: {数据}")
# 计算平均值
if 统计信息["有效数据量"] > 0:
统计信息["平均值"] = 统计信息["数据总和"] / 统计信息["有效数据量"]
else:
统计信息["平均值"] = 0
return 统计信息
# 测试数据分析工具
测试数据 = [1, 2, None, 3, "无效", 4, 5, "STOP", 6, 7, 8]
统计结果 = 数据分析工具(测试数据)
print("\n数据分析结果:")
for 指标, 值 in 统计结果.items():
if 指标 == "处理的数据":
print(f" {指标}: {值}")
elif isinstance(值, float):
print(f" {指标}: {值:.2f}")
else:
print(f" {指标}: {值}")4.6 列表推导式与生成器表达式
列表推导式和生成器表达式是Python中非常强大且简洁的语法,用于创建列表和生成器。
列表推导式(List Comprehensions)
# 基础列表推导式
# 语法:[expression for item in iterable if condition]
# 创建平方数列表
平方数 = [x**2 for x in range(1, 11)]
print(f"1-10的平方数: {平方数}")
# 过滤偶数
偶数 = [x for x in range(1, 21) if x % 2 == 0]
print(f"1-20的偶数: {偶数}")
# 复杂条件
结果 = [x for x in range(1, 31) if x % 3 == 0 and x % 5 == 0]
print(f"1-30中能同时被3和5整除的数: {结果}")
# 字符串处理
单词列表 = ["apple", "banana", "cherry", "date", "elderberry"]
大写单词 = [单词.upper() for 单词 in 单词列表]
print(f"大写单词: {大写单词}")
# 带if-else条件的列表推导式
奇偶标签 = ["偶数" if x % 2 == 0 else "奇数" for x in range(1, 11)]
print(f"奇偶标签: {奇偶标签}")
# 嵌套循环
矩阵 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
扁平化 = [元素 for 行 in 矩阵 for 元素 in 行]
print(f"矩阵: {矩阵}")
print(f"扁平化: {扁平化}")
# 实际应用:数据转换
def 处理学生成绩(原始成绩):
"""将百分制成绩转换为等级制"""
# 使用列表推导式转换
等级列表 = []
for 成绩 in 原始成绩:
if 成绩 >= 90:
等级列表.append("A")
elif 成绩 >= 80:
等级列表.append("B")
elif 成绩 >= 70:
等级列表.append("C")
elif 成绩 >= 60:
等级列表.append("D")
else:
等级列表.append("F")
# 使用列表推导式简化
等级列表2 = [
"A" if 成绩 >= 90 else
"B" if 成绩 >= 80 else
"C" if 成绩 >= 70 else
"D" if 成绩 >= 60 else
"F"
for 成绩 in 原始成绩
]
return 等级列表, 等级列表2
# 测试成绩转换
原始成绩 = [85, 92, 78, 45, 67, 100, 55]
等级1, 等级2 = 处理学生成绩(原始成绩)
print(f"\n原始成绩: {原始成绩}")
print(f"传统方法转换: {等级1}")
print(f"列表推导式转换: {等级2}")
print(f"结果相同: {等级1 == 等级2}")生成器表达式(Generator Expressions)
# 生成器表达式
# 语法:(expression for item in iterable if condition)
# 创建生成器
平方生成器 = (x**2 for x in range(1, 11))
print(f"平方生成器: {平方生成器}")
print(f"转换为列表: {list(平方生成器)}")
# 注意:生成器只能迭代一次
平方生成器 = (x**2 for x in range(1, 6))
print("第一次迭代生成器:")
for 值 in 平方生成器:
print(f" {值}")
print("第二次迭代生成器(为空):")
for 值 in 平方生成器:
print(f" {值}") # 不会执行,因为生成器已经耗尽
# 生成器表达式的优势:节省内存
import sys
# 列表推导式:一次性创建所有元素
列表 = [x**2 for x in range(1000000)]
print(f"列表内存占用: {sys.getsizeof(列表):,} 字节")
# 生成器表达式:一次生成一个元素
生成器 = (x**2 for x in range(1000000))
print(f"生成器内存占用: {sys.getsizeof(生成器):,} 字节")
# 使用生成器处理大数据
def 处理大数据(数据量):
"""演示生成器处理大数据的优势"""
print(f"\n处理{数据量:,}条数据:")
# 使用列表(占用大量内存)
开始时间 = 时间.time()
列表数据 = [x for x in range(数据量)]
列表总和 = sum(列表数据)
列表耗时 = 时间.time() - 开始时间
print(f" 列表方式: 耗时{列表耗时:.4f}秒,内存占用高")
# 使用生成器(节省内存)
开始时间 = 时间.time()
生成器数据 = (x for x in range(数据量))
生成器总和 = sum(生成器数据)
生成器耗时 = 时间.time() - 开始时间
print(f" 生成器方式: 耗时{生成器耗时:.4f}秒,内存占用低")
# 注意:需要导入time模块
import time
处理大数据(10000000) # 1000万条数据
# 生成器表达式在函数调用中的应用
# 可以直接作为函数参数
数字列表 = [1, 2, 3, 4, 5]
平方和 = sum(x**2 for x in 数字列表)
print(f"\n数字列表: {数字列表}")
print(f"平方和: {平方和}")
# 查找最大值
最大值 = max(x**2 for x in 数字列表)
print(f"最大平方值: {最大值}")
# 实际应用:读取大文件
def 统计大文件行数(文件名):
"""统计大文件的行数(使用生成器节省内存)"""
行数 = 0
with open(文件名, 'r', encoding='utf-8') as 文件:
# 使用生成器表达式逐行读取
行生成器 = (行 for 行 in 文件)
for 行 in 行生成器:
行数 += 1
return 行数
# 注意:需要实际文件来测试
# 行数 = 统计大文件行数("大文件.txt")
# print(f"文件行数: {行数}")
# 生成器表达式与条件过滤
# 统计文本中长度大于3的单词
文本 = "Python is a powerful programming language"
长单词 = (单词 for 单词 in 文本.split() if len(单词) > 3)
print(f"\n文本: {文本}")
print(f"长度大于3的单词: {list(长单词)}")字典和集合推导式
# 字典推导式
# 语法:{key_expression: value_expression for item in iterable if condition}
# 创建数字平方字典
平方字典 = {x: x**2 for x in range(1, 11)}
print(f"数字平方字典: {平方字典}")
# 转换列表为字典
键列表 = ["a", "b", "c", "d"]
值列表 = [1, 2, 3, 4]
字典 = {键: 值 for 键, 值 in zip(键列表, 值列表)}
print(f"列表转字典: {字典}")
# 过滤字典
原始字典 = {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}
偶数值字典 = {k: v for k, v in 原始字典.items() if v % 2 == 0}
print(f"原始字典: {原始字典}")
print(f"偶数值字典: {偶数值字典}")
# 键值交换
交换字典 = {v: k for k, v in 原始字典.items()}
print(f"键值交换字典: {交换字典}")
# 集合推导式
# 语法:{expression for item in iterable if condition}
# 创建平方数集合
平方集合 = {x**2 for x in range(1, 11)}
print(f"\n平方数集合: {平方集合}")
# 从列表创建不重复元素的集合
重复列表 = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
不重复集合 = {x for x in 重复列表}
print(f"重复列表: {重复列表}")
print(f"不重复集合: {不重复集合}")
# 复杂转换
字符串列表 = ["apple", "banana", "cherry", "date"]
首字母集合 = {单词[0].upper() for 单词 in 字符串列表}
print(f"字符串列表: {字符串列表}")
print(f"首字母集合: {首字母集合}")
# 实际应用:数据清洗
def 清洗数据(原始数据):
"""清洗数据,去除无效值和重复项"""
# 去除None和空字符串
清洗后列表 = [
项目.strip()
for 项目 in 原始数据
if 项目 is not None and str(项目).strip() != ""
]
# 转换为集合去重,再转回列表
去重列表 = list({项目 for 项目 in 清洗后列表})
return 去重列表
# 测试数据清洗
原始数据 = ["apple", "banana", "", "apple", None, "cherry", " ", "banana", "date"]
清洗结果 = 清洗数据(原始数据)
print(f"\n原始数据: {原始数据}")
print(f"清洗结果: {清洗结果}")4.7 条件表达式(三元运算符)
条件表达式(也称为三元运算符)提供了一种简洁的方式来根据条件选择两个值中的一个。
基础语法
# 基本语法:value_if_true if condition else value_if_false
# 简单的条件表达式
年龄 = 18
状态 = "成年" if 年龄 >= 18 else "未成年"
print(f"年龄{age}: {状态}")
# 传统写法
if 年龄 >= 18:
状态 = "成年"
else:
状态 = "未成年"
# 数值比较
a = 10
b = 20
较大值 = a if a > b else b
print(f"a={a}, b={b}, 较大值={较大值}")
# 字符串处理
字符串 = "Python"
结果 = "大写" if 字符串.isupper() else "非大写"
print(f"字符串'{字符串}': {结果}")
# 嵌套条件表达式
成绩 = 85
等级 = (
"A" if 成绩 >= 90 else
"B" if 成绩 >= 80 else
"C" if 成绩 >= 70 else
"D" if 成绩 >= 60 else
"F"
)
print(f"成绩{成绩}: 等级{等级}")
# 注意:嵌套太多会降低可读性
# 复杂情况下建议使用if-elif-else结构实际应用
# 应用1:设置默认值
def 获取配置(配置字典, 键, 默认值=None):
"""从配置字典获取值,如果不存在则返回默认值"""
值 = 配置字典.get(键, 默认值)
# 使用条件表达式处理特殊情况
值 = 值 if 值 is not None else "未设置"
return 值
配置 = {"语言": "Python", "版本": "3.11"}
print(f"语言: {获取配置(配置, '语言')}")
print(f"作者: {获取配置(配置, '作者')}")
print(f"版本: {获取配置(配置, '版本', '未知')}")
# 应用2:数据验证和转换
def 安全转换为整数(字符串, 默认值=0):
"""安全地将字符串转换为整数"""
try:
return int(字符串)
except (ValueError, TypeError):
return 默认值
# 使用条件表达式简化
def 安全转换为整数简洁版(字符串, 默认值=0):
"""安全地将字符串转换为整数(简洁版)"""
return int(字符串) if 字符串 and 字符串.isdigit() else 默认值
# 测试
测试数据 = ["123", "abc", "", None, "45.6"]
print("\n安全转换为整数测试:")
for 数据 in 测试数据:
结果1 = 安全转换为整数(数据)
结果2 = 安全转换为整数简洁版(数据)
print(f" 输入: {数据!r:10} -> 方法1: {结果1}, 方法2: {结果2}")
# 应用3:格式化输出
def 格式化成绩(学生, 成绩):
"""格式化成绩输出,根据成绩添加颜色标记"""
# 使用条件表达式选择颜色
颜色 = (
"\033[92m" if 成绩 >= 90 else # 绿色
"\033[93m" if 成绩 >= 80 else # 黄色
"\033[91m" if 成绩 >= 60 else # 红色
"\033[91;1m" # 红色加粗(不及格)
)
重置 = "\033[0m"
return f"{颜色}{学生}: {成绩}分{重置}"
# 测试格式化成绩
print("\n格式化成绩输出:")
学生成绩 = [("张三", 95), ("李四", 85), ("王五", 75), ("赵六", 55)]
for 学生, 成绩 in 学生成绩:
print(f" {格式化成绩(学生, 成绩)}")
# 应用4:在列表推导式中使用条件表达式
def 处理数字列表(数字列表):
"""处理数字列表,将负数转换为0"""
处理后 = [x if x >= 0 else 0 for x in 数字列表]
return 处理后
# 测试
原始列表 = [1, -2, 3, -4, 5, -6, 7]
处理列表 = 处理数字列表(原始列表)
print(f"\n原始列表: {原始列表}")
print(f"处理列表(负数转0): {处理列表}")
# 更复杂的列表推导式
def 分类数字(数字列表):
"""将数字分类为"正数"、"零"或"负数""""
分类 = [
"正数" if x > 0 else
"零" if x == 0 else
"负数"
for x in 数字列表
]
return 分类
# 测试
数字列表 = [5, -3, 0, 8, -1, 0, 2]
分类结果 = 分类数字(数字列表)
print(f"\n数字列表: {数字列表}")
print(f"分类结果: {分类结果}")条件表达式的局限性
# 条件表达式不适合复杂逻辑
def 复杂的业务逻辑(用户类型, 订单金额, 优惠券=None):
"""复杂的业务逻辑,不适合用条件表达式"""
# 传统的if-elif-else更清晰
if 用户类型 == "VIP":
if 优惠券 == "DISCOUNT50":
折扣 = 0.5
else:
折扣 = 0.2
elif 用户类型 == "普通会员":
if 订单金额 > 1000:
折扣 = 0.1
else:
折扣 = 0
else:
折扣 = 0
# 尝试用条件表达式(不推荐,难以阅读)
折扣 = (
0.5 if 用户类型 == "VIP" and 优惠券 == "DISCOUNT50" else
0.2 if 用户类型 == "VIP" else
0.1 if 用户类型 == "普通会员" and 订单金额 > 1000 else
0 if 用户类型 == "普通会员" else
0
)
return 折扣
# 条件表达式与语句的区别
def 条件表达式与语句的区别():
"""展示条件表达式和条件语句的区别"""
# 条件表达式返回一个值
结果1 = "偶数" if 10 % 2 == 0 else "奇数"
# 条件语句不返回值,只执行操作
if 10 % 2 == 0:
结果2 = "偶数"
else:
结果2 = "奇数"
print(f"条件表达式结果: {结果1}")
print(f"条件语句结果: {结果2}")
# 错误示例:条件表达式不能包含语句
# 以下代码会引发语法错误:
# x = print("A") if True else print("B")
# 正确:使用条件语句
if True:
print("A")
else:
print("B")
条件表达式与语句的区别()4.8 控制流综合实例
现在让我们将所有学到的控制流知识应用到实际项目中。
项目1:简单的学生成绩管理系统
class 学生成绩管理系统:
"""简单的学生成绩管理系统"""
def __init__(self):
self.学生数据 = {}
def 添加学生(self, 学号, 姓名):
"""添加学生"""
if 学号 in self.学生数据:
print(f"错误:学号{学号}已存在!")
return False
self.学生数据[学号] = {
"姓名": 姓名,
"成绩": {}
}
print(f"成功添加学生:{姓名}(学号:{学号})")
return True
def 添加成绩(self, 学号, 科目, 成绩):
"""添加或更新成绩"""
if 学号 not in self.学生数据:
print(f"错误:学号{学号}不存在!")
return False
if not (0 <= 成绩 <= 100):
print(f"错误:成绩必须在0-100之间!")
return False
self.学生数据[学号]["成绩"][科目] = 成绩
print(f"成功为{self.学生数据[学号]['姓名']}添加{科目}成绩:{成绩}")
return True
def 查询学生(self, 学号):
"""查询学生信息"""
if 学号 not in self.学生数据:
print(f"错误:学号{学号}不存在!")
return None
学生 = self.学生数据[学号]
信息 = f"学号:{学号}\n姓名:{学生['姓名']}"
if 学生["成绩"]:
信息 += "\n成绩:"
for 科目, 成绩 in 学生["成绩"].items():
等级 = (
"A" if 成绩 >= 90 else
"B" if 成绩 >= 80 else
"C" if 成绩 >= 70 else
"D" if 成绩 >= 60 else
"F"
)
信息 += f"\n {科目}: {成绩}分 ({等级})"
# 计算平均分
成绩列表 = list(学生["成绩"].values())
平均分 = sum(成绩列表) / len(成绩列表)
信息 += f"\n平均分: {平均分:.1f}"
else:
信息 += "\n暂无成绩记录"
return 信息
def 统计信息(self):
"""统计系统信息"""
if not self.学生数据:
return "系统中没有学生数据"
学生总数 = len(self.学生数据)
有成绩学生数 = 0
所有成绩 = []
for 学号, 学生 in self.学生数据.items():
if 学生["成绩"]:
有成绩学生数 += 1
所有成绩.extend(学生["成绩"].values())
统计 = f"""
统计信息:
==========
学生总数:{学生总数}
有成绩学生数:{有成绩学生数}
无成绩学生数:{学生总数 - 有成绩学生数}
"""
if 所有成绩:
最高分 = max(所有成绩)
最低分 = min(所有成绩)
平均分 = sum(所有成绩) / len(所有成绩)
统计 += f"""
成绩统计:
最高分:{最高分}
最低分:{最低分}
平均分:{平均分:.1f}
分数段分布:
90-100分:{len([x for x in 所有成绩 if x >= 90])}人
80-89分:{len([x for x in 所有成绩 if 80 <= x < 90])}人
70-79分:{len([x for x in 所有成绩 if 70 <= x < 80])}人
60-69分:{len([x for x in 所有成绩 if 60 <= x < 70])}人
0-59分:{len([x for x in 所有成绩 if x < 60])}人
"""
return 统计
def 运行(self):
"""运行管理系统"""
print("=" * 50)
print("学生成绩管理系统")
print("=" * 50)
while True:
print("\n功能菜单:")
print("1. 添加学生")
print("2. 添加成绩")
print("3. 查询学生")
print("4. 查看统计")
print("5. 退出系统")
选择 = input("请选择操作(1-5): ")
if 选择 == "1":
学号 = input("请输入学号: ")
姓名 = input("请输入姓名: ")
self.添加学生(学号, 姓名)
elif 选择 == "2":
学号 = input("请输入学号: ")
科目 = input("请输入科目: ")
while True:
成绩输入 = input("请输入成绩(0-100): ")
try:
成绩 = int(成绩输入)
if 0 <= 成绩 <= 100:
self.添加成绩(学号, 科目, 成绩)
break
else:
print("成绩必须在0-100之间!")
except ValueError:
print("请输入有效的数字!")
elif 选择 == "3":
学号 = input("请输入学号: ")
信息 = self.查询学生(学号)
if 信息:
print(f"\n{信息}")
elif 选择 == "4":
统计 = self.统计信息()
print(统计)
elif 选择 == "5":
print("感谢使用,再见!")
break
else:
print("无效选择,请重新输入!")
# 运行系统
print("学生成绩管理系统演示:")
系统 = 学生成绩管理系统()
# 添加测试数据
系统.添加学生("001", "张三")
系统.添加学生("002", "李四")
系统.添加学生("003", "王五")
系统.添加成绩("001", "数学", 85)
系统.添加成绩("001", "英语", 92)
系统.添加成绩("002", "数学", 78)
系统.添加成绩("002", "英语", 88)
系统.添加成绩("003", "数学", 95)
系统.添加成绩("003", "英语", 90)
# 查询学生
print("\n查询学生测试:")
print(系统.查询学生("001"))
print("\n" + "="*40)
print(系统.查询学生("002"))
# 查看统计
print("\n" + "="*40)
print("系统统计:")
print(系统.统计信息())
# 注意:这里我们注释掉完整运行,以免阻塞程序执行
# 系统.运行()项目2:猜单词游戏
import random
class 猜单词游戏:
"""猜单词游戏"""
def __init__(self):
# 单词库
self.单词库 = [
"python", "programming", "computer", "algorithm",
"database", "network", "software", "hardware",
"internet", "keyboard", "monitor", "developer",
"function", "variable", "constant", "iteration",
"recursion", "syntax", "semantic", "compiler"
]
self.最高分 = 0
self.游戏次数 = 0
def 选择单词(self):
"""随机选择一个单词"""
return random.choice(self.单词库)
def 初始化游戏状态(self, 单词):
"""初始化游戏状态"""
单词长度 = len(单词)
已猜字母 = set()
当前进度 = ["_"] * 单词长度
剩余尝试次数 = 6 # 最多允许6次错误
return {
"单词": 单词,
"单词长度": 单词长度,
"已猜字母": 已猜字母,
"当前进度": 当前进度,
"剩余尝试次数": 剩余尝试次数,
"正确字母数": 0,
"开始时间": None,
"结束时间": None
}
def 显示进度(self, 状态):
"""显示当前游戏进度"""
单词 = 状态["单词"]
进度 = " ".join(状态["当前进度"])
已猜字母 = ", ".join(sorted(状态["已猜字母"])) if 状态["已猜字母"] else "无"
图形 = self.绘制绞刑架(状态["剩余尝试次数"])
显示信息 = f"""
{图形}
单词:{进度}
单词长度:{状态["单词长度"]}个字母
已猜字母:{已猜字母}
剩余尝试次数:{状态["剩余尝试次数"]}
正确字母数:{状态["正确字母数"]}/{状态["单词长度"]}
"""
print(显示信息)
def 绘制绞刑架(self, 剩余尝试次数):
"""绘制绞刑架图形"""
图形 = [
"""
+---+
| |
|
|
|
|
=========
""",
"""
+---+
| |
O |
|
|
|
=========
""",
"""
+---+
| |
O |
| |
|
|
=========
""",
"""
+---+
| |
O |
/| |
|
|
=========
""",
"""
+---+
| |
O |
/|\\ |
|
|
=========
""",
"""
+---+
| |
O |
/|\\ |
/ |
|
=========
""",
"""
+---+
| |
O |
/|\\ |
/ \\ |
|
=========
"""
]
return 图形[6 - 剩余尝试次数]
def 处理猜测(self, 状态, 猜测):
"""处理玩家的猜测"""
单词 = 状态["单词"].lower()
猜测 = 猜测.lower()
# 检查输入有效性
if not 猜测:
return "请输入一个字母!", False
if len(猜测) != 1:
return "每次只能猜一个字母!", False
if not 猜测.isalpha():
return "请输入英文字母!", False
# 检查是否已经猜过这个字母
if 猜测 in 状态["已猜字母"]:
return f"你已经猜过字母 '{猜测}' 了!", False
# 添加到已猜字母集合
状态["已猜字母"].add(猜测)
# 检查猜测是否正确
if 猜测 in 单词:
# 更新进度
for i, 字母 in enumerate(单词):
if 字母 == 猜测:
状态["当前进度"][i] = 猜测
状态["正确字母数"] += 1
消息 = f"恭喜!字母 '{猜测}' 在单词中。"
正确 = True
else:
状态["剩余尝试次数"] -= 1
消息 = f"抱歉,字母 '{猜测}' 不在单词中。"
正确 = False
return 消息, 正确
def 检查游戏状态(self, 状态):
"""检查游戏是否结束"""
# 检查是否猜对了所有字母
if 状态["正确字母数"] == 状态["单词长度"]:
return "胜利"
# 检查是否用完了尝试次数
if 状态["剩余尝试次数"] <= 0:
return "失败"
# 游戏继续
return "继续"
def 计算得分(self, 状态, 游戏结果):
"""计算游戏得分"""
if 游戏结果 != "胜利":
return 0
# 基础分:单词长度 * 10
基础分 = 状态["单词长度"] * 10
# 奖励分:剩余尝试次数 * 5
奖励分 = 状态["剩余尝试次数"] * 5
# 惩罚分:已猜字母数(包括错误的)* 2
惩罚分 = len(状态["已猜字母"]) * 2
总分 = 基础分 + 奖励分 - 惩罚分
# 最低分为0
return max(总分, 0)
def 运行游戏(self):
"""运行一次游戏"""
import time
print("=" * 50)
print("猜单词游戏")
print("=" * 50)
# 选择单词
单词 = self.选择单词()
状态 = self.初始化游戏状态(单词)
状态["开始时间"] = time.time()
print(f"\n游戏开始!我已经想好了一个{状态['单词长度']}个字母的单词。")
# 游戏主循环
while True:
self.显示进度(状态)
# 获取玩家输入
猜测 = input("请输入你猜测的字母: ")
# 处理猜测
消息, 正确 = self.处理猜测(状态, 猜测)
print(f"\n{消息}")
# 检查游戏状态
游戏结果 = self.检查游戏状态(状态)
if 游戏结果 == "胜利":
状态["结束时间"] = time.time()
用时 = 状态["结束时间"] - 状态["开始时间"]
得分 = self.计算得分(状态, 游戏结果)
print(f"\n恭喜你!你赢了!")
print(f"单词是: {状态['单词']}")
print(f"用时: {用时:.1f}秒")
print(f"得分: {得分}")
# 更新最高分
if 得分 > self.最高分:
self.最高分 = 得分
print(f"新最高分: {self.最高分}!")
break
elif 游戏结果 == "失败":
状态["结束时间"] = time.time()
用时 = 状态["结束时间"] - 状态["开始时间"]
print(f"\n游戏结束!你输了。")
print(f"单词是: {状态['单词']}")
print(f"用时: {用时:.1f}秒")
break
self.游戏次数 += 1
return 游戏结果
def 运行(self):
"""运行游戏主循环"""
while True:
结果 = self.运行游戏()
# 询问是否继续
继续 = input("\n是否继续游戏?(y/n): ").lower()
if 继续 != 'y':
print(f"\n感谢游玩!")
print(f"游戏次数: {self.游戏次数}")
print(f"最高分: {self.最高分}")
break
# 运行游戏
print("猜单词游戏演示:")
游戏 = 猜单词游戏()
# 运行一次演示游戏
print("\n运行一次演示游戏:")
游戏.运行游戏()
# 注意:这里我们注释掉完整运行,以免阻塞程序执行
# 游戏.运行()项目3:数据分析工具
import statistics
class 数据分析工具:
"""数据分析工具"""
def __init__(self):
self.数据集 = []
def 加载数据(self, 数据源):
"""从不同源加载数据"""
if isinstance(数据源, list):
self.数据集 = 数据源
print(f"从列表加载了{len(数据源)}条数据")
elif isinstance(数据源, str):
# 假设是CSV文件路径
try:
with open(数据源, 'r', encoding='utf-8') as 文件:
# 读取数据,假设每行一个数字
self.数据集 = []
for 行号, 行 in enumerate(文件, 1):
行 = 行.strip()
if 行 and not 行.startswith('#'): # 跳过空行和注释
try:
self.数据集.append(float(行))
except ValueError:
print(f"警告:第{行号}行不是有效的数字: {行}")
print(f"从文件加载了{len(self.数据集)}条有效数据")
except FileNotFoundError:
print(f"错误:文件'{数据源}'不存在")
self.数据集 = []
else:
print("错误:不支持的数据源类型")
self.数据集 = []
def 基础统计(self):
"""计算基础统计信息"""
if not self.数据集:
return "数据集为空"
统计 = {
"数据量": len(self.数据集),
"总和": sum(self.数据集),
"平均值": statistics.mean(self.数据集) if len(self.数据集) > 0 else 0,
"中位数": statistics.median(self.数据集) if len(self.数据集) > 0 else 0,
"众数": statistics.mode(self.数据集) if len(self.数据集) > 1 else self.数据集[0] if self.数据集 else None,
"标准差": statistics.stdev(self.数据集) if len(self.数据集) > 1 else 0,
"最小值": min(self.数据集),
"最大值": max(self.数据集),
"范围": max(self.数据集) - min(self.数据集),
}
return 统计
def 数据分布(self, 分组数=10):
"""分析数据分布"""
if not self.数据集:
return "数据集为空"
最小值 = min(self.数据集)
最大值 = max(self.数据集)
范围 = 最大值 - 最小值
if 范围 == 0:
return "所有数据值相同"
# 计算组距
组距 = 范围 / 分组数
# 创建分组边界
分组边界 = [最小值 + i * 组距 for i in range(分组数 + 1)]
# 统计每个分组的数量
分组统计 = {i: 0 for i in range(分组数)}
for 值 in self.数据集:
# 确定值属于哪个分组
for i in range(分组数):
if 分组边界[i] <= 值 < 分组边界[i + 1]:
分组统计[i] += 1
break
else:
# 处理最大值(包含在最后一个分组)
if 值 == 最大值:
分组统计[分组数 - 1] += 1
# 创建分布报告
分布报告 = []
for i in range(分组数):
下限 = 分组边界[i]
上限 = 分组边界[i + 1]
数量 = 分组统计[i]
百分比 = (数量 / len(self.数据集)) * 100
# 创建简单的条形图
条形长度 = int(百分比 / 2) # 缩放以便显示
条形图 = "█" * 条形长度 if 条形长度 > 0 else "▏"
分布报告.append({
"分组": i + 1,
"范围": f"{下限:.2f} - {上限:.2f}",
"数量": 数量,
"百分比": 百分比,
"条形图": 条形图
})
return 分布报告
def 异常值检测(self, 阈值=1.5):
"""检测异常值(使用IQR方法)"""
if len(self.数据集) < 4:
return "数据量不足,无法检测异常值"
# 排序数据
排序数据 = sorted(self.数据集)
# 计算四分位数
Q1 = statistics.median(排序数据[:len(排序数据)//2])
Q3 = statistics.median(排序数据[(len(排序数据)+1)//2:])
# 计算IQR(四分位距)
IQR = Q3 - Q1
# 计算异常值边界
下边界 = Q1 - 阈值 * IQR
上边界 = Q3 + 阈值 * IQR
# 找出异常值
异常值 = [x for x in self.数据集 if x < 下边界 or x > 上边界]
正常值 = [x for x in self.数据集 if 下边界 <= x <= 上边界]
return {
"Q1(第一四分位数)": Q1,
"Q3(第三四分位数)": Q3,
"IQR(四分位距)": IQR,
"下边界": 下边界,
"上边界": 上边界,
"异常值数量": len(异常值),
"异常值": 异常值,
"正常值数量": len(正常值),
}
def 数据清洗(self):
"""清洗数据,去除异常值和无效数据"""
if not self.数据集:
return "数据集为空"
原始长度 = len(self.数据集)
# 去除None和字符串
清洗后数据 = [x for x in self.数据集 if isinstance(x, (int, float))]
# 去除NaN和无穷大
清洗后数据 = [x for x in 清洗后数据 if x == x and abs(x) != float('inf')]
# 检测并去除异常值
异常值信息 = self.异常值检测()
if isinstance(异常值信息, dict):
正常值 = 异常值信息.get("正常值", [])
清洗后数据 = 正常值
清洗后长度 = len(清洗后数据)
去除数量 = 原始长度 - 清洗后长度
self.数据集 = 清洗后数据
return {
"原始数据量": 原始长度,
"清洗后数据量": 清洗后长度,
"去除数据量": 去除数量,
"去除百分比": (去除数量 / 原始长度 * 100) if 原始长度 > 0 else 0
}
def 生成报告(self):
"""生成完整的数据分析报告"""
if not self.数据集:
return "数据集为空"
报告 = []
报告.append("=" * 60)
报告.append("数据分析报告")
报告.append("=" * 60)
报告.append("")
# 基础统计
基础统计信息 = self.基础统计()
报告.append("基础统计信息:")
报告.append("-" * 40)
for 指标, 值 in 基础统计信息.items():
if isinstance(值, float):
报告.append(f" {指标:10}: {值:.4f}")
else:
报告.append(f" {指标:10}: {值}")
报告.append("")
# 数据分布
分布信息 = self.数据分布()
报告.append("数据分布:")
报告.append("-" * 40)
for 分组信息 in 分布信息:
报告.append(f" 分组{分组信息['分组']:2}: {分组信息['范围']:20} "
f"数量: {分组信息['数量']:4} "
f"({分组信息['百分比']:5.1f}%) {分组信息['条形图']}")
报告.append("")
# 异常值检测
异常值信息 = self.异常值检测()
报告.append("异常值检测:")
报告.append("-" * 40)
for 指标, 值 in 异常值信息.items():
if isinstance(值, list):
if 值:
报告.append(f" {指标}: {值}")
else:
报告.append(f" {指标}: 无")
elif isinstance(值, float):
报告.append(f" {指标:20}: {值:.4f}")
else:
报告.append(f" {指标:20}: {值}")
return "\n".join(报告)
# 使用示例
print("数据分析工具演示:")
# 创建测试数据
测试数据 = []
import random
for _ in range(100):
# 生成一些正常数据
测试数据.append(random.normalvariate(100, 15))
# 添加一些异常值
if random.random() < 0.05: # 5%的概率
测试数据.append(random.normalvariate(200, 50))
# 添加一些无效数据
测试数据.append(None)
测试数据.append("无效数据")
测试数据.append(float('nan'))
print(f"原始数据量: {len(测试数据)}")
print(f"数据示例(前10个): {测试数据[:10]}")
# 创建分析工具实例
分析工具 = 数据分析工具()
分析工具.加载数据(测试数据)
# 生成报告
报告 = 分析工具.生成报告()
print("\n" + 报告)
# 数据清洗
清洗结果 = 分析工具.数据清洗()
print("\n数据清洗结果:")
for 指标, 值 in 清洗结果.items():
if isinstance(值, float):
print(f" {指标}: {值:.2f}")
else:
print(f" {指标}: {值}")
# 清洗后的报告
print("\n清洗后的数据分析报告:")
清洗后报告 = 分析工具.生成报告()
print(清洗后报告)总结:掌握控制流,解锁编程的真正力量
通过本章的学习,你已经掌握了Python中控制流的核心概念:
- 条件语句(if、elif、else):让程序能够根据不同的条件做出决策
- 循环语句(while、for):让程序能够重复执行任务
- 循环控制(break、continue、pass):精细控制循环的执行流程
- 列表推导式和生成器表达式:简洁高效地创建和转换数据
- 条件表达式:简洁的条件判断语法
控制流是编程的基础,也是让代码变得"智能"的关键。记住以下最佳实践:
最佳实践总结
- 保持条件简单:复杂的条件判断应该分解或使用函数封装
- 避免深层嵌套:深层嵌套的条件和循环难以理解和维护
- 使用合适的循环:
- 知道循环次数时使用
for循环 - 不确定循环次数但知道终止条件时使用
while循环
- 知道循环次数时使用
- 善用列表推导式:但要注意可读性,过于复杂的推导式不如使用普通循环
- 及时使用break和continue:可以提高循环效率和代码清晰度
- 优先使用条件表达式:简单的条件判断用条件表达式更简洁
下一步学习
在下一章中,我们将学习函数与模块。函数是组织代码的基本单位,模块是组织函数和类的方式。通过学习函数,你可以:
- 将复杂的代码分解为可重用的部分
- 提高代码的可读性和可维护性
- 减少代码重复
实践是最好的老师。尝试完成以下练习来巩固本章所学:
练习题
FizzBuzz游戏:编写一个程序,打印1到100的数字。但是对于3的倍数打印"Fizz",对于5的倍数打印"Buzz",对于既是3又是5的倍数打印"FizzBuzz"。
素数判断器:编写一个函数,判断一个数是否为素数,然后找出1-1000之间的所有素数。
密码生成器:编写一个程序,生成指定长度的随机密码,包含大小写字母、数字和特殊字符。
数据过滤器:编写一个函数,接收一个列表和一个过滤函数,返回过滤后的新列表。
简易计算器:使用控制流实现一个支持加、减、乘、除的计算器,能够处理用户输入和错误。
进一步挑战
- 尝试将本章的综合实例扩展为更完整的应用程序
- 使用控制流解决一个你实际遇到的问题
- 研究Python中的
match-case语句(Python 3.10+的新特性)
控制流是编程的基石,掌握它之后,你将能够解决更复杂的问题。记住:编程不是记住所有语法,而是学会如何解决问题。
本文是《Python入门与进阶实践》的第四章,涵盖了Python控制流的全面内容。通过大量的代码示例和实际项目,你应该已经掌握了条件语句和循环语句的核心概念。在后续章节中,我们将继续深入学习Python的其他重要概念。
相关资源:
代码下载:本章完整代码示例
下一章预告:第5章 函数与模块 - 学习如何将代码组织成可重用的函数和模块。