Skip to content

Python控制流:条件与循环的艺术

控制流是编程的决策中枢,它让程序从简单的指令序列转变为智能的逻辑系统。掌握条件与循环,你就掌握了让代码"思考"和"重复工作"的能力。

前言:从顺序执行到智能决策

在前面的章节中,我们学习了Python的基础语法和数据类型。你可能会有一个疑问:"如果...那么..."这样的逻辑如何在代码中表达? 或者 "如何让代码重复执行某个任务直到满足条件?"

这就是控制流要解决的问题。控制流决定了代码的执行顺序,让程序能够根据不同的条件做出不同的决策,或者重复执行某些操作直到满足特定条件。

让我用一个生活中的例子来解释:假设你要根据天气决定穿什么衣服:

  • 顺序执行:就是不管天气如何,都穿同一套衣服
  • 条件判断:如果下雨,穿雨衣;如果晴天,穿T恤;如果下雪,穿羽绒服
  • 循环:每天都检查天气预报并决定穿什么,直到冬天结束

在本章中,我们将深入学习Python中的条件语句和循环语句,让你的代码从"机械执行"变为"智能决策"。

4.1 条件语句:if、elif、else

条件语句是编程中的决策者,它让程序能够根据不同的条件执行不同的代码块。

基础语法:if语句

python
# 最简单的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结构

python
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}): {类型}")

使用逻辑运算符组合条件

python
# 检查用户名和密码
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 嵌套条件语句

嵌套条件语句是指在一个条件语句的代码块中包含另一个条件语句。这允许我们处理更复杂的决策逻辑。

基础嵌套示例

python
# 简单的嵌套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"  {状态}: {角色} {操作} {资源} -> {消息}")

多层嵌套与扁平化

python
# 多层嵌套示例(可能变得难以阅读)
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}")

实际应用:游戏角色状态判断

python
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循环

python
# 基本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循环的实际应用

python
# 模拟银行取款
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循环

python
# 遍历列表
水果列表 = ["苹果", "香蕉", "橙子", "葡萄", "芒果"]

print("遍历水果列表:")
for 水果 in 水果列表:
    print(f"  我喜欢吃{水果}")

# 遍历字符串
文本 = "Python编程"
print("\n遍历字符串:")
for 字符 in 文本:
    print(f"  字符: {字符}")

# 遍历字典
学生信息 = {
    "姓名": "张三",
    "年龄": 20,
    "专业": "计算机科学",
    "成绩": {"数学": 90, "英语": 85}
}

print("\n遍历字典:")
forin 学生信息:
    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循环的实际应用

python
# 统计列表信息
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语句:提前退出循环

python
# 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语句:跳过当前迭代

python
# 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语句:占位符

python
# 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"  处理数字: {数字}")

循环控制综合示例

python
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)

python
# 基础列表推导式
# 语法:[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]]
扁平化 = [元素 forin 矩阵 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)

python
# 生成器表达式
# 语法:(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("第一次迭代生成器:")
forin 平方生成器:
    print(f"  {}")

print("第二次迭代生成器(为空):")
forin 平方生成器:
    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 文件:
        # 使用生成器表达式逐行读取
        行生成器 = (行 forin 文件)
        forin 行生成器:
            行数 += 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(长单词)}")

字典和集合推导式

python
# 字典推导式
# 语法:{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 条件表达式(三元运算符)

条件表达式(也称为三元运算符)提供了一种简洁的方式来根据条件选择两个值中的一个。

基础语法

python
# 基本语法: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结构

实际应用

python
# 应用1:设置默认值
def 获取配置(配置字典, 键, 默认值=None):
    """从配置字典获取值,如果不存在则返回默认值"""
= 配置字典.get(键, 默认值)
    # 使用条件表达式处理特殊情况
=ifis 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"分类结果: {分类结果}")

条件表达式的局限性

python
# 条件表达式不适合复杂逻辑
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:简单的学生成绩管理系统

python
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:猜单词游戏

python
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:数据分析工具

python
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()
                        ifand 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(分组数)}

        forin 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中控制流的核心概念:

  1. 条件语句(if、elif、else):让程序能够根据不同的条件做出决策
  2. 循环语句(while、for):让程序能够重复执行任务
  3. 循环控制(break、continue、pass):精细控制循环的执行流程
  4. 列表推导式和生成器表达式:简洁高效地创建和转换数据
  5. 条件表达式:简洁的条件判断语法

控制流是编程的基础,也是让代码变得"智能"的关键。记住以下最佳实践:

最佳实践总结

  1. 保持条件简单:复杂的条件判断应该分解或使用函数封装
  2. 避免深层嵌套:深层嵌套的条件和循环难以理解和维护
  3. 使用合适的循环
    • 知道循环次数时使用for循环
    • 不确定循环次数但知道终止条件时使用while循环
  4. 善用列表推导式:但要注意可读性,过于复杂的推导式不如使用普通循环
  5. 及时使用break和continue:可以提高循环效率和代码清晰度
  6. 优先使用条件表达式:简单的条件判断用条件表达式更简洁

下一步学习

在下一章中,我们将学习函数与模块。函数是组织代码的基本单位,模块是组织函数和类的方式。通过学习函数,你可以:

  • 将复杂的代码分解为可重用的部分
  • 提高代码的可读性和可维护性
  • 减少代码重复

实践是最好的老师。尝试完成以下练习来巩固本章所学:

练习题

  1. FizzBuzz游戏:编写一个程序,打印1到100的数字。但是对于3的倍数打印"Fizz",对于5的倍数打印"Buzz",对于既是3又是5的倍数打印"FizzBuzz"。

  2. 素数判断器:编写一个函数,判断一个数是否为素数,然后找出1-1000之间的所有素数。

  3. 密码生成器:编写一个程序,生成指定长度的随机密码,包含大小写字母、数字和特殊字符。

  4. 数据过滤器:编写一个函数,接收一个列表和一个过滤函数,返回过滤后的新列表。

  5. 简易计算器:使用控制流实现一个支持加、减、乘、除的计算器,能够处理用户输入和错误。

进一步挑战

  1. 尝试将本章的综合实例扩展为更完整的应用程序
  2. 使用控制流解决一个你实际遇到的问题
  3. 研究Python中的match-case语句(Python 3.10+的新特性)

控制流是编程的基石,掌握它之后,你将能够解决更复杂的问题。记住:编程不是记住所有语法,而是学会如何解决问题


本文是《Python入门与进阶实践》的第四章,涵盖了Python控制流的全面内容。通过大量的代码示例和实际项目,你应该已经掌握了条件语句和循环语句的核心概念。在后续章节中,我们将继续深入学习Python的其他重要概念。

相关资源

代码下载本章完整代码示例

下一章预告:第5章 函数与模块 - 学习如何将代码组织成可重用的函数和模块。

热爱生活,喜好美食,追求未来!