====== 第二章 控制流 ====== ===== 本章概要 ===== 控制流是编程的核心概念,它决定了程序执行的顺序和路径。本章将深入学习Python中的条件语句、循环结构和推导式,让你能够编写更复杂的程序逻辑。 ===== 2.1 条件语句 ===== ==== 2.1.1 if 语句 ==== 最基本的条件语句,当条件为真时执行代码块。 age = 18 if age >= 18: print("你已经成年了") ==== 2.1.2 if-else 语句 ==== 提供两个执行分支。 age = 16 if age >= 18: print("你已经成年了") else: print("你还未成年") ==== 2.1.3 if-elif-else 语句 ==== 处理多个条件。 score = 85 if score >= 90: grade = "A" elif score >= 80: grade = "B" elif score >= 70: grade = "C" elif score >= 60: grade = "D" else: grade = "F" print(f"成绩等级: {grade}") ==== 2.1.4 嵌套条件语句 ==== 在条件语句内部再写条件语句。 age = 25 has_id = True if age >= 18: if has_id: print("可以进入") else: print("请出示证件") else: print("未成年人禁止进入") ==== 2.1.5 三元表达式 ==== 简洁的条件表达式。 age = 20 status = "成年" if age >= 18 else "未成年" print(status) # 成年 # 等效于 if age >= 18: status = "成年" else: status = "未成年" ==== 2.1.6 条件判断的真值 ==== 以下值被视为 ``False``: # 假值 False None 0 0.0 0j # 复数0 "" # 空字符串 [] # 空列表 {} # 空字典 () # 空元组 set() # 空集合 # 示例 name = "" if not name: print("名字不能为空") items = [] if not items: print("列表为空") ==== 2.1.7 逻辑组合条件 ==== # and - 两个条件都满足 age = 25 income = 5000 if age >= 18 and income >= 3000: print("符合贷款条件") # or - 任一条件满足 weekend = True holiday = False if weekend or holiday: print("今天休息") # not - 条件取反 is_closed = False if not is_closed: print("商店营业中") # 组合使用 x = 15 if (x > 10 and x < 20) or x == 0: print("x在10到20之间,或x等于0") ==== 2.1.8 match-case 结构(Python 3.10+) ==== 结构模式匹配,类似于其他语言的switch语句。 def http_status(status): match status: case 200: return "OK" case 404: return "Not Found" case 500: return "Server Error" case _: return "Unknown Status" # 带守卫子句的匹配 def describe_number(n): match n: case 0: return "零" case x if x > 0: return f"正数: {x}" case x if x < 0: return f"负数: {x}" # 匹配数据结构 def handle_command(command): match command: case ["load", filename]: print(f"加载文件: {filename}") case ["save", filename]: print(f"保存文件: {filename}") case ["quit"]: print("退出程序") case _: print("未知命令") handle_command(["load", "data.txt"]) ===== 2.2 循环语句 ===== ==== 2.2.1 while 循环 ==== 当条件为真时重复执行代码块。 # 基本while循环 count = 0 while count < 5: print(f"计数: {count}") count += 1 print("循环结束") === while-else 结构 === 当循环正常结束时(没有被break),执行else块。 # 查找列表中的第一个负数 numbers = [1, 2, 3, 4, 5] i = 0 while i < len(numbers): if numbers[i] < 0: print(f"找到负数: {numbers[i]}") break i += 1 else: print("列表中没有负数") === 无限循环 === # 用户输入直到输入'quit' while True: command = input("请输入命令 (quit退出): ") if command.lower() == "quit": print("程序退出") break print(f"执行命令: {command}") ==== 2.2.2 for 循环 ==== 遍历序列或其他可迭代对象。 # 遍历列表 fruits = ["apple", "banana", "cherry"] for fruit in fruits: print(fruit) # 遍历字符串 for char in "Python": print(char, end=" ") # P y t h o n # 遍历字典 student = {"name": "Alice", "age": 20, "grade": "A"} for key in student: print(f"{key}: {student[key]}") # 遍历键值对 for key, value in student.items(): print(f"{key}: {value}") === range() 函数 === 生成数字序列。 # range(stop) for i in range(5): print(i, end=" ") # 0 1 2 3 4 # range(start, stop) for i in range(2, 6): print(i, end=" ") # 2 3 4 5 # range(start, stop, step) for i in range(0, 10, 2): print(i, end=" ") # 0 2 4 6 8 # 倒序 for i in range(10, 0, -1): print(i, end=" ") # 10 9 8 7 6 5 4 3 2 1 === enumerate() 函数 === 同时获取索引和值。 fruits = ["apple", "banana", "cherry"] # 使用enumerate for index, fruit in enumerate(fruits): print(f"{index}: {fruit}") # 指定起始索引 for index, fruit in enumerate(fruits, start=1): print(f"{index}. {fruit}") === zip() 函数 === 并行遍历多个序列。 names = ["Alice", "Bob", "Charlie"] ages = [25, 30, 35] cities = ["北京", "上海", "广州"] for name, age, city in zip(names, ages, cities): print(f"{name}, {age}岁, 来自{city}") # zip对象可以转换为列表/字典 pairs = list(zip(names, ages)) print(pairs) # [('Alice', 25), ('Bob', 30), ('Charlie', 35)] ==== 2.2.3 循环控制语句 ==== === break 语句 === 立即退出循环。 # 查找第一个大于10的数 numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] for num in numbers: if num > 10: print(f"找到: {num}") break === continue 语句 === 跳过当前迭代,继续下一次循环。 # 打印奇数 for i in range(10): if i % 2 == 0: continue print(i, end=" ") # 1 3 5 7 9 === pass 语句 === 占位符,不做任何事情。 # 待实现的函数 def future_function(): pass # 稍后实现 # 空的循环体 for i in range(10): pass # 暂不处理 === 嵌套循环 === # 打印乘法表 for i in range(1, 10): for j in range(1, i + 1): print(f"{j}×{i}={i*j:2d}", end=" ") print() # 遍历二维列表 matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] for row in matrix: for item in row: print(item, end=" ") print() ==== 2.2.4 循环中的else子句 ==== # 查找质数 for n in range(2, 20): for x in range(2, n): if n % x == 0: print(f"{n} = {x} * {n//x}") break else: # 循环没有被break,说明是质数 print(f"{n} 是质数") ===== 2.3 推导式 ===== 推导式(Comprehension)是Python特有的简洁语法,用于从可迭代对象创建新的数据结构。 ==== 2.3.1 列表推导式 ==== 基本语法: [表达式 for 变量 in 可迭代对象 if 条件] 示例: # 创建平方数列表 squares = [x**2 for x in range(10)] print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] # 带条件的列表推导式 evens = [x for x in range(20) if x % 2 == 0] print(evens) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # 处理字符串 words = ["Hello", "World", "Python", "Programming"] lengths = [len(word) for word in words] print(lengths) # [5, 5, 6, 11] # 嵌套列表推导式 matrix = [[i*j for j in range(1, 4)] for i in range(1, 4)] print(matrix) # [[1, 2, 3], [2, 4, 6], [3, 6, 9]] # 展平嵌套列表 nested = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] flat = [item for sublist in nested for item in sublist] print(flat) # [1, 2, 3, 4, 5, 6, 7, 8, 9] ==== 2.3.2 字典推导式 ==== # 基本语法:{键: 值 for 变量 in 可迭代对象} # 创建平方数字典 squares_dict = {x: x**2 for x in range(6)} print(squares_dict) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25} # 交换键值 original = {"a": 1, "b": 2, "c": 3} swapped = {v: k for k, v in original.items()} print(swapped) # {1: 'a', 2: 'b', 3: 'c'} # 过滤字典 scores = {"Alice": 85, "Bob": 92, "Charlie": 78, "David": 95} passed = {k: v for k, v in scores.items() if v >= 80} print(passed) # {'Alice': 85, 'Bob': 92, 'David': 95} ==== 2.3.3 集合推导式 ==== # 基本语法:{表达式 for 变量 in 可迭代对象} # 创建平方集合 squares_set = {x**2 for x in range(20)} print(squares_set) # 去重后的平方数 # 从字符串创建集合 chars = {c.lower() for c in "Hello World" if c.isalpha()} print(chars) # {'h', 'e', 'l', 'o', 'w', 'r', 'd'} ==== 2.3.4 生成器表达式 ==== 与列表推导式类似,但返回生成器对象,惰性求值,节省内存。 # 生成器表达式 squares_gen = (x**2 for x in range(1000000)) # 逐个获取值 print(next(squares_gen)) # 0 print(next(squares_gen)) # 1 # 在循环中使用 for square in (x**2 for x in range(10)): print(square, end=" ") # 0 1 4 9 16 25 36 49 64 81 # 与sum()等函数配合使用 total = sum(x**2 for x in range(1000)) print(f"\n0到999的平方和: {total}") ==== 2.3.5 推导式 vs 循环 ==== 比较: # 传统循环方式 evens = [] for x in range(20): if x % 2 == 0: evens.append(x) # 列表推导式(更简洁、更快) evens = [x for x in range(20) if x % 2 == 0] 何时使用推导式: * 逻辑简单、可读性好 * 需要创建新的数据结构 * 性能要求高 何时使用循环: * 逻辑复杂 * 需要执行副作用(如打印、文件操作) * 需要多行代码完成 ===== 2.4 代码示例 ===== ==== 示例1:猜数字游戏 ==== import random secret = random.randint(1, 100) attempts = 0 max_attempts = 7 print("猜数字游戏!我想了一个1到100之间的数字。") while attempts < max_attempts: guess = int(input(f"第{attempts + 1}次尝试,请输入你的猜测: ")) attempts += 1 if guess < secret: print("太小了!") elif guess > secret: print("太大了!") else: print(f"恭喜你猜对了!答案就是{secret}。") print(f"你用了{attempts}次猜中。") break else: print(f"游戏结束!正确答案是{secret}。") ==== 示例2:斐波那契数列 ==== def fibonacci(n): """生成前n个斐波那契数""" a, b = 0, 1 for _ in range(n): yield a a, b = b, a + b # 打印前20个斐波那契数 print("斐波那契数列:") for i, num in enumerate(fibonacci(20), 1): print(f"F({i}) = {num}") ==== 示例3:文本分析器 ==== text = """ Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。 Python由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年。 Python源代码遵循GPL协议。 """ # 统计字符 char_count = len(text) print(f"总字符数: {char_count}") # 统计单词 words = text.split() word_count = len(words) print(f"单词数: {word_count}") # 统计行数 lines = text.strip().split('\n') line_count = len(lines) print(f"行数: {line_count}") # 统计每个字符出现的频率(只统计字母) from collections import Counter letters = [c.lower() for c in text if c.isalpha()] frequency = Counter(letters) print("\n字符频率(前10):") for char, count in frequency.most_common(10): print(f" {char}: {count}") ===== 2.5 练习题 ===== ==== 练习1:九九乘法表 ==== 使用嵌套循环打印九九乘法表。 # 参考答案 for i in range(1, 10): for j in range(1, i + 1): print(f"{j}×{i}={i*j:2d}", end=" ") print() ==== 练习2:判断质数 ==== 编写函数判断一个数是否为质数。 # 参考答案 def is_prime(n): if n < 2: return False for i in range(2, int(n**0.5) + 1): if n % i == 0: return False return True # 测试 for num in range(1, 101): if is_prime(num): print(num, end=" ") ==== 练习3:列表去重并排序 ==== 使用集合推导式去除列表中的重复元素并排序。 # 参考答案 numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] # 方法1:使用集合推导式 unique_sorted = sorted({x for x in numbers}) print(unique_sorted) # [1, 2, 3, 4, 5, 6, 9] # 方法2:使用dict.fromkeys()(保持插入顺序) unique_ordered = list(dict.fromkeys(numbers)) print(unique_ordered) # [3, 1, 4, 5, 9, 2, 6] ==== 练习4:打印金字塔 ==== 编写程序打印金字塔图案。 # 参考答案 def print_pyramid(height): for i in range(height): spaces = " " * (height - i - 1) stars = "*" * (2 * i + 1) print(spaces + stars) print_pyramid(5) # 输出: # * # *** # ***** # ******* # ********* ==== 练习5:回文检查 ==== 编写函数检查字符串是否为回文。 # 参考答案 def is_palindrome(s): # 去除非字母数字字符并转为小写 cleaned = ''.join(c.lower() for c in s if c.isalnum()) return cleaned == cleaned[::-1] # 测试 test_strings = ["A man a plan a canal Panama", "Hello", "racecar", "12321"] for s in test_strings: print(f"'{s}' -> {is_palindrome(s)}") ===== 本章小结 ===== 本章学习了Python的控制流语句: * **条件语句** - if、elif、else、三元表达式、match-case * **循环语句** - while、for、range、enumerate、zip * **循环控制** - break、continue、pass、else子句 * **推导式** - 列表、字典、集合推导式,生成器表达式 掌握控制流后,你可以编写具有复杂逻辑的Python程序了。下一章将学习函数,让代码更加模块化和可重用。 ===== 进一步阅读 ===== * [[https://docs.python.org/zh-cn/3/tutorial/controlflow.html|Python官方教程 - 控制流]] * [[https://docs.python.org/zh-cn/3/reference/compound_stmts.html|复合语句参考]]