课程 6:控制流复习

📚 学习目标

控制流复习简介:
控制流是编程的核心概念,决定了程序的执行路径。本课程将系统复习Python中的条件语句(if-elif-else)和循环语句(for、while),通过大量实例和练习,帮助学生掌握控制流的各种用法和最佳实践。

1. 条件语句复习

1.1 if语句基础

🎯 基本if语句

if语句用于根据条件决定是否执行特定的代码块。

# 基本if语句
age = 18
if age >= 18:
    print("成年人")
    print("可以投票")

# if-else语句
score = 85
if score >= 60:
    print("及格")
else:
    print("不及格")

# if-elif-else语句
grade = 85
if grade >= 90:
    print("优秀")
elif grade >= 80:
    print("良好")
elif grade >= 70:
    print("中等")
elif grade >= 60:
    print("及格")
else:
    print("不及格")

1.2 复杂条件判断

🔍 复杂条件示例

# 多重条件判断
age = 25
income = 50000
credit_score = 750

# 使用逻辑运算符组合条件
if age >= 18 and income >= 30000 and credit_score >= 700:
    print("符合贷款条件")
elif age >= 18 and income >= 50000:
    print("部分符合条件,需要提高信用分数")
else:
    print("不符合贷款条件")

# 嵌套if语句
username = "admin"
password = "123456"
is_active = True

if username == "admin":
    if password == "123456":
        if is_active:
            print("登录成功")
    else:
            print("账户已被禁用")
    else:
        print("密码错误")
else:
    print("用户名不存在")

# 使用in运算符
fruits = ["apple", "banana", "orange"]
fruit = "apple"

if fruit in fruits:
    print(f"{fruit}在水果列表中")
else:
    print(f"{fruit}不在水果列表中")

1.3 match语句(结构模式匹配)

🎯 match语句基础(Python 3.10+)

match语句是Python 3.10引入的新特性,提供了一种更优雅的方式来处理多个条件分支。

# 基本match语句
def analyze_command(command):
    match command:
        case "start":
            return "启动系统"
        case "stop":
            return "停止系统"
        case "restart":
            return "重启系统"
        case _:  # 默认情况
            return "未知命令"

# 测试match语句
print(analyze_command("start"))  # 启动系统
print(analyze_command("unknown"))  # 未知命令

# 带值的模式匹配
def analyze_status(status):
    match status:
        case 200:
            return "成功"
        case 404:
            return "未找到"
        case 500:
            return "服务器错误"
        case code if 100 <= code < 200:
            return "信息响应"
        case code if 300 <= code < 400:
            return "重定向"
        case code if 400 <= code < 500:
            return "客户端错误"
        case code if 500 <= code < 600:
            return "服务器错误"
        case _:
            return "未知状态码"

# 测试状态码分析
print(analyze_status(200))  # 成功
print(analyze_status(404))  # 未找到
print(analyze_status(301))  # 重定向

🔍 高级模式匹配

# 解构模式匹配
def analyze_point(point):
    match point:
        case (0, 0):
            return "原点"
        case (0, y):
            return f"Y轴上的点,y={y}"
        case (x, 0):
            return f"X轴上的点,x={x}"
        case (x, y):
            return f"普通点({x}, {y})"
        case _:
            return "无效点"

# 测试点分析
print(analyze_point((0, 0)))    # 原点
print(analyze_point((0, 5)))    # Y轴上的点,y=5
print(analyze_point((3, 0)))    # X轴上的点,x=3
print(analyze_point((2, 3)))    # 普通点(2, 3)

# 列表模式匹配
def analyze_list(lst):
    match lst:
        case []:
            return "空列表"
        case [x]:
            return f"单元素列表: {x}"
        case [x, y]:
            return f"双元素列表: {x}, {y}"
        case [x, y, z]:
            return f"三元素列表: {x}, {y}, {z}"
        case [first, *rest]:
            return f"多元素列表,首元素: {first},其余: {rest}"
        case _:
            return "无效列表"

# 测试列表分析
print(analyze_list([]))           # 空列表
print(analyze_list([1]))          # 单元素列表: 1
print(analyze_list([1, 2]))       # 双元素列表: 1, 2
print(analyze_list([1, 2, 3, 4])) # 多元素列表,首元素: 1,其余: [2, 3, 4]

# 字典模式匹配
def analyze_config(config):
    match config:
        case {"type": "user", "name": name, "age": age}:
            return f"用户配置: {name}, {age}岁"
        case {"type": "admin", "name": name, "permissions": perms}:
            return f"管理员配置: {name}, 权限: {perms}"
        case {"type": "guest"}:
            return "访客配置"
        case {"type": type_name, **rest}:
            return f"其他类型配置: {type_name}, 其他参数: {rest}"
        case _:
            return "无效配置"

# 测试配置分析
print(analyze_config({"type": "user", "name": "Alice", "age": 25}))
print(analyze_config({"type": "admin", "name": "Bob", "permissions": ["read", "write"]}))
print(analyze_config({"type": "guest"}))

🎮 实际应用示例

# 游戏状态管理
def handle_game_command(command, player_state):
    match command:
        case ["move", direction]:
            return f"玩家向{direction}方向移动"
        case ["attack", target]:
            return f"玩家攻击{target}"
        case ["use", item, target]:
            return f"玩家使用{item}在{target}上"
        case ["inventory"]:
            return "显示背包"
        case ["quit"]:
            return "退出游戏"
        case _:
            return "未知命令"

# 测试游戏命令
print(handle_game_command(["move", "north"], {}))
print(handle_game_command(["attack", "goblin"], {}))
print(handle_game_command(["use", "potion", "self"], {}))

# HTTP请求处理
def handle_http_request(method, path, headers):
    match (method, path):
        case ("GET", "/"):
            return {"status": 200, "content": "首页"}
        case ("GET", "/users" | "/users/"):
            return {"status": 200, "content": "用户列表"}
        case ("GET", f"/users/{user_id}"):
            return {"status": 200, "content": f"用户{user_id}信息"}
        case ("POST", "/users"):
            return {"status": 201, "content": "用户创建成功"}
        case ("PUT", f"/users/{user_id}"):
            return {"status": 200, "content": f"用户{user_id}更新成功"}
        case ("DELETE", f"/users/{user_id}"):
            return {"status": 204, "content": f"用户{user_id}删除成功"}
        case _:
            return {"status": 404, "content": "页面未找到"}

# 测试HTTP请求处理
print(handle_http_request("GET", "/", {}))
print(handle_http_request("GET", "/users/123", {}))
print(handle_http_request("POST", "/users", {}))

# 数据类型分析
def analyze_data(data):
    match data:
        case None:
            return "空值"
        case bool():
            return f"布尔值: {data}"
        case int():
            return f"整数: {data}"
        case float():
            return f"浮点数: {data}"
        case str():
            return f"字符串: {data}"
        case list():
            return f"列表,长度: {len(data)}"
        case dict():
            return f"字典,键数: {len(data)}"
        case _:
            return f"其他类型: {type(data).__name__}"

# 测试数据类型分析
print(analyze_data(None))
print(analyze_data(42))
print(analyze_data("Hello"))
print(analyze_data([1, 2, 3]))
print(analyze_data({"a": 1, "b": 2}))

⚡ match vs if-elif-else 对比

# 使用if-elif-else的传统方式
def analyze_command_traditional(command):
    if command == "start":
        return "启动系统"
    elif command == "stop":
        return "停止系统"
    elif command == "restart":
        return "重启系统"
    else:
        return "未知命令"

# 使用match的现代方式
def analyze_command_modern(command):
    match command:
        case "start":
            return "启动系统"
        case "stop":
            return "停止系统"
        case "restart":
            return "重启系统"
        case _:
            return "未知命令"

# 复杂条件对比
def analyze_user_traditional(user):
    if isinstance(user, dict):
        if user.get("type") == "admin":
            if user.get("permissions"):
                return f"管理员,权限: {user['permissions']}"
            else:
                return "管理员,无特殊权限"
        elif user.get("type") == "user":
            return f"普通用户: {user.get('name', 'Unknown')}"
        else:
            return "未知用户类型"
    else:
        return "无效用户数据"

def analyze_user_modern(user):
    match user:
        case {"type": "admin", "permissions": perms}:
            return f"管理员,权限: {perms}"
        case {"type": "admin"}:
            return "管理员,无特殊权限"
        case {"type": "user", "name": name}:
            return f"普通用户: {name}"
        case {"type": "user"}:
            return "普通用户: Unknown"
        case _:
            return "无效用户数据"

# 测试对比
user1 = {"type": "admin", "permissions": ["read", "write"]}
user2 = {"type": "user", "name": "Alice"}

print(analyze_user_traditional(user1))
print(analyze_user_modern(user1))
print(analyze_user_traditional(user2))
print(analyze_user_modern(user2))

2. 循环语句复习

2.1 for循环

🔄 for循环基础

# 遍历列表
fruits = ["apple", "banana", "orange"]
for fruit in fruits:
    print(f"我喜欢{fruit}")

# 遍历字符串
for char in "Python":
    print(char)

# 使用range()函数
for i in range(5):
    print(i)  # 0, 1, 2, 3, 4

for i in range(1, 6):
    print(i)  # 1, 2, 3, 4, 5

for i in range(0, 10, 2):
    print(i)  # 0, 2, 4, 6, 8

# 遍历字典
person = {"name": "Alice", "age": 25, "city": "Beijing"}
for key in person:
    print(f"{key}: {person[key]}")

for key, value in person.items():
    print(f"{key}: {value}")

# 使用enumerate()获取索引
fruits = ["apple", "banana", "orange"]
for index, fruit in enumerate(fruits):
    print(f"{index}: {fruit}")

2.2 while循环

⏳ while循环基础

# 基本while循环
    count = 0
while count < 5:
    print(f"计数: {count}")
    count += 1

# 用户输入循环
password = "secret"
attempts = 0
max_attempts = 3

while attempts < max_attempts:
    user_input = input("请输入密码: ")
    if user_input == password:
        print("登录成功!")
        break
    else:
        attempts += 1
        print(f"密码错误,还剩{max_attempts - attempts}次机会")

# 无限循环与break
while True:
    user_input = input("请输入命令 (quit退出): ")
    if user_input.lower() == "quit":
        break
    print(f"执行命令: {user_input}")

# 使用continue跳过当前迭代
for i in range(10):
    if i % 2 == 0:
        continue  # 跳过偶数
    print(i)  # 只打印奇数

2.3 循环控制语句

🎛️ break、continue、else

# break语句 - 提前结束循环
for i in range(10):
    if i == 5:
        break
    print(i)  # 只打印0到4

# continue语句 - 跳过当前迭代
for i in range(10):
    if i == 5:
        continue
    print(i)  # 打印0-4, 6-9,跳过5

# else子句 - 循环正常结束时执行
for i in range(5):
    print(i)
else:
    print("循环正常结束")

# break时不会执行else
for i in range(5):
    if i == 3:
        break
    print(i)
else:
    print("这行不会执行")

# 实际应用:查找元素
numbers = [1, 3, 5, 7, 9]
search_value = 4

for num in numbers:
    if num == search_value:
        print(f"找到{search_value}")
        break
else:
    print(f"未找到{search_value}")

3. 嵌套控制流

3.1 条件语句嵌套

🏗️ 嵌套条件示例

# 嵌套if语句
age = 25
income = 50000
credit_score = 750

if age >= 18:
    if income >= 30000:
        if credit_score >= 700:
            print("完全符合贷款条件")
        elif credit_score >= 600:
            print("需要提高信用分数")
        else:
            print("信用分数过低")
    else:
        print("收入不足")
else:
    print("年龄不符合要求")

# 多层嵌套的实际应用
def check_eligibility(age, income, credit_score, employment_years):
    if age >= 18:
        if income >= 30000:
            if credit_score >= 700:
                if employment_years >= 2:
                    return "完全符合条件"
                else:
                    return "工作年限不足"
            elif credit_score >= 600:
                return "信用分数需要提高"
            else:
                return "信用分数过低"
        else:
            return "收入不足"
    else:
        return "年龄不符合要求"

# 测试函数
result = check_eligibility(25, 50000, 750, 3)
print(result)

3.2 循环嵌套

🔄 嵌套循环示例

# 打印乘法表
for i in range(1, 10):
    for j in range(1, i + 1):
        print(f"{j}×{i}={i*j}", end="\t")
    print()  # 换行

# 二维数组遍历
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

for row in matrix:
    for element in row:
        print(element, end=" ")
    print()

# 查找二维数组中的元素
def find_element(matrix, target):
    for i, row in enumerate(matrix):
        for j, element in enumerate(row):
            if element == target:
                return (i, j)
    return None

# 测试查找函数
result = find_element(matrix, 5)
print(f"元素5的位置: {result}")

# 嵌套循环中的break和continue
for i in range(3):
    for j in range(3):
        if i == 1 and j == 1:
            break  # 只跳出内层循环
        print(f"({i}, {j})")
    print("内层循环结束")

4. 控制流最佳实践

4.1 代码优化技巧

⚡ 优化技巧

# 1. 使用早期返回减少嵌套
def check_loan_eligibility(age, income, credit_score):
    if age < 18:
        return "年龄不符合要求"
    
    if income < 30000:
        return "收入不足"
    
    if credit_score < 700:
        return "信用分数过低"
    
    return "符合贷款条件"

# 2. 使用列表推导式替代简单循环
# 传统方式
squares = []
for i in range(10):
    if i % 2 == 0:
        squares.append(i ** 2)

# 列表推导式
squares = [i ** 2 for i in range(10) if i % 2 == 0]

# 3. 使用any()和all()函数
numbers = [2, 4, 6, 8, 10]
all_even = all(num % 2 == 0 for num in numbers)
any_odd = any(num % 2 == 1 for num in numbers)

# 4. 使用enumerate()获取索引
fruits = ["apple", "banana", "orange"]
for index, fruit in enumerate(fruits, 1):
    print(f"{index}. {fruit}")

# 5. 使用zip()同时遍历多个列表
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
cities = ["Beijing", "Shanghai", "Guangzhou"]

for name, age, city in zip(names, ages, cities):
    print(f"{name} is {age} years old and lives in {city}")

4.2 常见陷阱和解决方案

⚠️ 常见陷阱

# 1. 可变默认参数陷阱
def add_item(item, items=[]):  # 错误:可变默认参数
    items.append(item)
    return items

# 正确做法
def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

# 2. 循环中修改列表
numbers = [1, 2, 3, 4, 5]
# 错误做法
for i in range(len(numbers)):
    if numbers[i] % 2 == 0:
        numbers.remove(numbers[i])  # 会跳过元素

# 正确做法
numbers = [num for num in numbers if num % 2 != 0]

# 3. 浮点数比较
# 错误做法
if 0.1 + 0.2 == 0.3:
    print("相等")

# 正确做法
if abs(0.1 + 0.2 - 0.3) < 1e-10:
    print("相等")

# 4. 无限循环
# 错误做法
i = 0
while i < 10:
    print(i)
    # 忘记增加i

# 正确做法
i = 0
while i < 10:
    print(i)
    i += 1

5. 实际应用案例

5.1 学生成绩管理系统

📊 成绩管理示例

# 学生成绩管理系统
students = [
    {"name": "Alice", "scores": [85, 90, 78, 92]},
    {"name": "Bob", "scores": [72, 68, 85, 79]},
    {"name": "Charlie", "scores": [95, 88, 92, 96]},
    {"name": "Diana", "scores": [65, 70, 68, 72]}
]

def calculate_average(scores):
    return sum(scores) / len(scores)

def get_grade(average):
    if average >= 90:
        return "A"
    elif average >= 80:
        return "B"
    elif average >= 70:
        return "C"
    elif average >= 60:
        return "D"
    else:
        return "F"

def analyze_students():
    print("学生成绩分析报告")
    print("=" * 40)
    
    for student in students:
        name = student["name"]
        scores = student["scores"]
        average = calculate_average(scores)
        grade = get_grade(average)
        
        print(f"学生: {name}")
        print(f"成绩: {scores}")
        print(f"平均分: {average:.2f}")
        print(f"等级: {grade}")
        
        # 分析各科成绩
        for i, score in enumerate(scores, 1):
            if score >= 90:
                print(f"  科目{i}: 优秀")
            elif score >= 80:
                print(f"  科目{i}: 良好")
            elif score >= 70:
                print(f"  科目{i}: 中等")
            elif score >= 60:
                print(f"  科目{i}: 及格")
            else:
                print(f"  科目{i}: 不及格")
        
        print("-" * 40)

# 运行分析
analyze_students()

5.2 简单游戏逻辑

🎮 猜数字游戏

import random

def guess_number_game():
    # 生成1-100的随机数
    target = random.randint(1, 100)
    attempts = 0
    max_attempts = 10
    
    print("欢迎来到猜数字游戏!")
    print(f"我已经想好了一个1-100之间的数字,你有{max_attempts}次机会猜测。")
    
    while attempts < max_attempts:
        try:
            guess = int(input(f"第{attempts + 1}次猜测,请输入数字: "))
            attempts += 1
            
            if guess < 1 or guess > 100:
                print("请输入1-100之间的数字!")
                continue
            
            if guess == target:
                print(f"恭喜!你用了{attempts}次就猜对了!")
                break
            elif guess < target:
                print("太小了,再大一点!")
            else:
                print("太大了,再小一点!")
            
            # 提示剩余次数
            remaining = max_attempts - attempts
            if remaining > 0:
                print(f"还有{remaining}次机会")
            
        except ValueError:
            print("请输入有效的数字!")
            continue
    
    else:
        print(f"游戏结束!正确答案是{target}")

# 运行游戏
if __name__ == "__main__":
    guess_number_game()

6. 控制流总结

✅ 控制流要点总结

⚠️ 注意事项

温馨提示:控制流是编程的基础,多练习各种条件判断和循环结构,掌握最佳实践,避免常见陷阱。
作业6:控制流综合练习

基础练习:
1. 编写一个程序,使用if-elif-else语句判断用户输入的年份是否为闰年。

2. 创建一个程序,使用for循环打印九九乘法表。

现代语法练习:
3. 使用match语句重写第1题的闰年判断程序。

4. 编写一个程序,使用match语句处理不同的HTTP状态码(200、404、500等)。

5. 使用match语句实现一个简单的计算器,支持加、减、乘、除四种运算。

进阶练习:
6. 编写一个猜数字游戏,使用while循环和break语句。

7. 创建一个程序,使用嵌套循环打印各种图案(如三角形、菱形等)。

模式匹配练习:
8. 使用match语句实现一个简单的游戏命令解析器,支持move、attack、use等命令。

9. 编写一个程序,使用match语句分析不同类型的数据结构(列表、字典、元组等)。

综合应用:
10. 实现一个简单的学生成绩管理系统,包含成绩录入、计算平均分、判断等级等功能。

11. 编写一个程序,使用控制流实现简单的计算器功能。

优化练习:
12. 使用列表推导式重写一些简单的循环逻辑。

13. 分析并优化一段包含多层嵌套的代码。

14. 对比if-elif-else和match语句的优缺点,在什么情况下使用哪种方式更合适?

提交要求:
- 所有代码必须包含详细注释 - 遵循Python编码规范 - 提供测试用例和运行结果 - 说明程序的设计思路 - 对于match语句的练习,请说明Python版本要求