全面解析Python流程控制语句及其使用案例
目录
1. 条件语句 (if/elif/else)
1.1 基本语法
age = 18
if age < 13:
category = "儿童"
elif age < 20:
category = "青少年" # 输出
else:
category = "成年人"
print(f"年龄分类: {category}")
1.2 三元表达式 (条件表达式)
# 传统写法
if score >= 60:
result = "及格"
else:
result = "不及格"
# 三元表达式 (更简洁)
result = "及格" if score >= 60 else "不及格"
# 嵌套三元表达式
grade = "优秀" if score >= 90 else "良好" if score >= 80 else "及格" if score >= 60 else "不及格"
1.3 真值判断
# Python中以下值被视为False:
# False, None, 0, 0.0, 0j, "", [], {}, (), set(), frozenset(), range(0)
# 检查列表是否为空
items = []
if items: # 不推荐: if len(items) > 0
print("列表不为空")
else:
print("列表为空") # 输出
# 检查变量是否为None
value = None
if value is None: # 推荐用is判断None
print("值为None")
# 同时检查多个条件
x = 10
if 5 < x < 15: # Python支持链式比较
print("x在5到15之间") # 输出
1.4 逻辑运算符
# and, or, not
age = 25
income = 5000
if age > 18 and income > 3000:
print("符合贷款条件")
# 短路求值
result = func_a() or func_b() # 如果func_a()返回真值,不执行func_b()
result = func_a() and func_b() # 如果func_a()返回假值,不执行func_b()
# 使用or提供默认值
username = user_input or "匿名用户"
2. 循环语句
2.1 for循环
基本遍历
# 遍历列表
fruits = ["苹果", "香蕉", "橙子"]
for fruit in fruits:
print(fruit)
# 遍历字符串
for char in "Python":
print(char, end="-") # P-y-t-h-o-n-
# 使用range()
for i in range(5): # 0, 1, 2, 3, 4
print(i)
for i in range(1, 10, 2): # 1, 3, 5, 7, 9
print(i)
使用enumerate获取索引
names = ["Alice", "Bob", "Charlie"]
# 不推荐
for i in range(len(names)):
print(f"{i}: {names[i]}")
# 推荐
for index, name in enumerate(names):
print(f"{index}: {name}")
# 指定起始索引
for index, name in enumerate(names, start=1):
print(f"{index}. {name}") # 1. Alice, 2. Bob, 3. Charlie
使用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以最短序列为准
short = [1, 2]
long = ["a", "b", "c", "d"]
for s, l in zip(short, long):
print(s, l) # 只输出两组
# Python 3.10+ zip_strict模式
# for x, y in zip(list1, list2, strict=True): # 长度不等会报错
遍历字典
user = {"name": "Alice", "age": 25, "city": "北京"}
# 遍历键
for key in user:
print(key)
# 遍历值
for value in user.values():
print(value)
# 遍历键值对
for key, value in user.items():
print(f"{key}: {value}")
# 遍历时修改字典 (需要list转换)
for key in list(user.keys()):
if key == "age":
del user[key]
反向遍历与排序遍历
# 反向遍历
for i in reversed(range(5)):
print(i) # 4, 3, 2, 1, 0
# 排序后遍历
for fruit in sorted(fruits, reverse=True):
print(fruit)
# 按值排序遍历字典
scores = {"Alice": 85, "Bob": 92, "Charlie": 78}
for name, score in sorted(scores.items(), key=lambda x: x[1], reverse=True):
print(f"{name}: {score}")
2.2 while循环
基本语法
# 基本while循环
count = 0
while count < 5:
print(count)
count += 1
# 无限循环 (需要break退出)
while True:
user_input = input("输入'quit'退出: ")
if user_input.lower() == 'quit':
break
print(f"你输入了: {user_input}")
while与else结合
# 查找质数
n = 17
divisor = 2
while divisor * divisor <= n:
if n % divisor == 0:
print(f"{n}不是质数,能被{divisor}整除")
break
divisor += 1
else:
# 循环正常结束(没有被break)时执行
print(f"{n}是质数")
3. 循环控制语句
3.1 break
# 查找第一个符合条件的元素
numbers = [1, 3, 5, 7, 8, 9, 10]
for num in numbers:
if num % 2 == 0:
print(f"找到第一个偶数: {num}") # 8
break
# 嵌套循环中的break (只退出当前层)
for i in range(3):
for j in range(3):
if j == 1:
break # 只退出内层循环
print(f"i={i}, j={j}")
3.2 continue
# 跳过某些元素
for num in range(10):
if num % 2 == 0:
continue # 跳过偶数
print(num) # 输出1, 3, 5, 7, 9
# 处理数据时跳过无效项
data = [1, 2, None, 4, None, 6]
for item in data:
if item is None:
continue
print(f"处理数据: {item}")
3.3 else子句
# for循环的else
target = 7
for i in range(5):
if i == target:
print("找到目标")
break
else:
print("未找到目标") # 输出,因为range(5)是0-4
# 实际应用:验证列表中所有元素
def all_positive(numbers):
for num in numbers:
if num <= 0:
print(f"发现非正数: {num}")
break
else:
print("所有数字都是正数")
return True
return False
all_positive([1, 2, 3, 4]) # 所有数字都是正数
all_positive([1, -2, 3, 4]) # 发现非正数: -2
4. 异常处理 (try/except)
4.1 基本结构
try:
result = 10 / 0
except ZeroDivisionError:
print("不能除以零!")
except TypeError:
print("类型错误!")
except Exception as e:
print(f"其他错误: {e}")
else:
print(f"计算结果: {result}") # 没有异常时执行
finally:
print("无论如何都会执行") # 清理资源
4.2 捕获多个异常
def safe_divide(a, b):
try:
result = a / b
except (ZeroDivisionError, TypeError) as e:
print(f"错误: {e}")
return None
return result
# 忽略特定异常
try:
risky_operation()
except SpecificError:
pass # 静默处理
4.3 自定义异常与raise
class ValidationError(Exception):
"""自定义验证错误"""
pass
def validate_age(age):
if age < 0:
raise ValidationError("年龄不能为负数")
if age > 150:
raise ValidationError("年龄不能超过150")
return True
# 使用from保留异常链
try:
int("not a number")
except ValueError as e:
raise RuntimeError("转换失败") from e
4.4 assert断言
def divide(a, b):
assert b != 0, "除数不能为零" # 开发调试时使用
return a / b
# 生产环境建议用异常处理代替assert
5. 上下文管理器 (with语句)
5.1 文件操作
# 传统写法
f = open('file.txt', 'r')
try:
content = f.read()
finally:
f.close()
# 使用with语句 (推荐)
with open('file.txt', 'r') as f:
content = f.read()
# 自动关闭文件,即使发生异常
# 同时管理多个资源
with open('input.txt', 'r') as infile, open('output.txt', 'w') as outfile:
outfile.write(infile.read())
5.2 自定义上下文管理器
from contextlib import contextmanager
class DatabaseConnection:
def __enter__(self):
print("连接数据库...")
self.conn = "数据库连接对象"
return self.conn
def __exit__(self, exc_type, exc_val, exc_tb):
print("关闭数据库连接...")
if exc_type:
print(f"发生异常: {exc_val}")
return False # 不抑制异常
# 使用
with DatabaseConnection() as conn:
print(f"使用{conn}进行操作")
# 使用装饰器简化
@contextmanager
def managed_resource(name):
print(f"获取资源: {name}")
resource = f"资源-{name}"
try:
yield resource
finally:
print(f"释放资源: {name}")
with managed_resource("数据库") as res:
print(f"使用{res}")
6. 推导式与生成器表达式
6.1 列表推导式
# 基本形式
squares = [x**2 for x in range(10)]
# 带条件
even_squares = [x**2 for x in range(10) if x % 2 == 0]
# 多重循环
combinations = [(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x != y]
# 嵌套列表推导式
matrix = [[i*j for j in range(1, 4)] for i in range(1, 4)]
# [[1, 2, 3], [2, 4, 6], [3, 6, 9]]
6.2 字典和集合推导式
# 字典推导式
word_lengths = {word: len(word) for word in ["apple", "banana", "cherry"]}
# {'apple': 5, 'banana': 6, 'cherry': 6}
# 集合推导式
unique_lengths = {len(word) for word in ["apple", "banana", "cherry", "date"]}
# {4, 5, 6}
6.3 生成器表达式
# 使用圆括号创建生成器 (惰性求值)
sum_of_squares = sum(x**2 for x in range(1000000)) # 内存友好
# 与列表推导式对比
list_comp = [x**2 for x in range(1000000)] # 占用大量内存
gen_exp = (x**2 for x in range(1000000)) # 几乎不占内存
# 生成器只能遍历一次
gen = (x for x in range(5))
print(list(gen)) # [0, 1, 2, 3, 4]
print(list(gen)) # [] (已耗尽)
7. 模式匹配 (match/case) Python 3.10+
7.1 基本匹配
def handle_command(command):
match command:
case "quit":
return "退出程序"
case "start":
return "开始运行"
case "stop":
return "停止运行"
case _: # 通配符,相当于default
return f"未知命令: {command}"
print(handle_command("start")) # 开始运行
print(handle_command("pause")) # 未知命令: pause
7.2 结构模式匹配
def describe_point(point):
match point:
case (0, 0):
return "原点"
case (x, 0):
return f"x轴上,x={x}"
case (0, y):
return f"y轴上,y={y}"
case (x, y):
return f"点({x}, {y})"
case _:
return "不是点"
print(describe_point((0, 0))) # 原点
print(describe_point((5, 0))) # x轴上,x=5
print(describe_point((3, 4))) # 点(3, 4)
7.3 匹配数据结构
def analyze_data(data):
match data:
case {"type": "user", "name": str(name), "age": int(age)}:
return f"用户: {name}, {age}岁"
case {"type": "product", "name": name, "price": price}:
return f"产品: {name}, 价格: {price}"
case [x, y, *rest]:
return f"列表,前两个元素: {x}, {y}, 其余: {rest}"
case _:
return "未知数据类型"
print(analyze_data({"type": "user", "name": "Alice", "age": 25}))
# 用户: Alice, 25岁
print(analyze_data([1, 2, 3, 4, 5]))
# 列表,前两个元素: 1, 2, 其余: [3, 4, 5]
7.4 带守卫子句的匹配
def classify_age(age):
match age:
case n if n < 0:
return "无效年龄"
case n if n < 13:
return "儿童"
case n if n < 20:
return "青少年"
case n if n < 60:
return "成年人"
case _:
return "老年人"
print(classify_age(25)) # 成年人
print(classify_age(-5)) # 无效年龄
8. 实战案例
8.1 菜单驱动程序
def show_menu():
print("\n" + "="*30)
print("1. 查看所有任务")
print("2. 添加任务")
print("3. 删除任务")
print("4. 标记完成")
print("5. 退出")
print("="*30)
def main():
tasks = []
while True:
show_menu()
choice = input("请选择操作 (1-5): ").strip()
match choice:
case "1":
if not tasks:
print("暂无任务")
else:
for i, task in enumerate(tasks, 1):
status = "✓" if task["done"] else "✗"
print(f"{i}. [{status}] {task['name']}")
case "2":
name = input("输入任务名称: ").strip()
if name:
tasks.append({"name": name, "done": False})
print("任务添加成功!")
case "3":
try:
idx = int(input("输入要删除的任务编号: ")) - 1
if 0 <= idx < len(tasks):
removed = tasks.pop(idx)
print(f"已删除: {removed['name']}")
else:
print("无效编号")
except ValueError:
print("请输入数字")
case "4":
try:
idx = int(input("输入要标记的任务编号: ")) - 1
if 0 <= idx < len(tasks):
tasks[idx]["done"] = True
print("标记完成!")
else:
print("无效编号")
except ValueError:
print("请输入数字")
case "5":
confirm = input("确定退出? (y/n): ").lower()
if confirm == 'y':
print("再见!")
break
case _:
print("无效选择,请重试")
if __name__ == "__main__":
main()
8.2 文件批处理
import os
from pathlib import Path
def batch_rename(directory, old_ext, new_ext):
"""批量修改文件扩展名"""
path = Path(directory)
if not path.exists():
print(f"目录不存在: {directory}")
return
files = list(path.glob(f"*.{old_ext}"))
if not files:
print(f"没有找到 .{old_ext} 文件")
return
print(f"找到 {len(files)} 个文件待处理")
confirm = input("确认重命名? (y/n): ").lower()
if confirm != 'y':
print("操作已取消")
return
success_count = 0
for file_path in files:
try:
new_name = file_path.stem + f".{new_ext}"
new_path = file_path.with_name(new_name)
file_path.rename(new_path)
print(f"重命名: {file_path.name} -> {new_name}")
success_count += 1
except Exception as e:
print(f"错误处理 {file_path.name}: {e}")
print(f"\n完成!成功重命名 {success_count}/{len(files)} 个文件")
# 使用示例
# batch_rename("./documents", "txt", "md")
8.3 数据验证器
from typing import Any, Dict, List
class DataValidator:
@staticmethod
def validate_user(data: Dict[str, Any]) -> Dict[str, str]:
errors = {}
# 验证必填字段
required = ["name", "email", "age"]
for field in required:
if field not in data:
errors[field] = f"缺少必填字段: {field}"
if errors:
return errors
# 验证name
name = data["name"]
if not isinstance(name, str):
errors["name"] = "name必须是字符串"
elif len(name) < 2:
errors["name"] = "name长度至少为2"
# 验证email
email = data["email"]
if not isinstance(email, str):
errors["email"] = "email必须是字符串"
elif "@" not in email:
errors["email"] = "email格式不正确"
# 验证age
age = data["age"]
if not isinstance(age, int):
errors["age"] = "age必须是整数"
elif not (0 <= age <= 150):
errors["age"] = "age必须在0-150之间"
return errors
# 使用示例
test_data = [
{"name": "A", "email": "test@example.com", "age": 25},
{"name": "Bob", "email": "invalid-email", "age": 200},
{"email": "test@example.com", "age": 25}, # 缺少name
]
for data in test_data:
errors = DataValidator.validate_user(data)
if errors:
print(f"验证失败: {errors}")
else:
print(f"验证通过: {data['name']}")
8.4 递归与迭代对比
# 斐波那契数列 - 递归版 (低效)
def fib_recursive(n):
if n <= 1:
return n
return fib_recursive(n-1) + fib_recursive(n-2)
# 斐波那契数列 - 迭代版 (高效)
def fib_iterative(n):
if n <= 1:
return n
a, b = 0, 1
for _ in range(2, n + 1):
a, b = b, a + b
return b
# 斐波那契数列 - 生成器版 (内存友好)
def fib_generator(max_n):
a, b = 0, 1
for _ in range(max_n):
yield a
a, b = b, a + b
# 性能对比
import time
n = 30
start = time.time()
result = fib_recursive(n)
print(f"递归版结果: {result}, 耗时: {time.time()-start:.4f}秒")
start = time.time()
result = fib_iterative(n)
print(f"迭代版结果: {result}, 耗时: {time.time()-start:.6f}秒")
print(f"生成器版前10项: {list(fib_generator(10))}")
总结
Python的控制结构以其简洁和可读性著称:
| 控制结构 | 关键特性 | 最佳实践 |
|---|---|---|
| if/elif/else | 链式比较、真值判断 | 避免嵌套过深,使用早期返回 |
| for循环 | 迭代协议、enumerate、zip | 优先用for而非while遍历序列 |
| while循环 | 条件控制、无限循环 | 确保有退出条件,避免死循环 |
| break/continue | 循环控制 | 适度使用,避免逻辑过于复杂 |
| try/except | 异常处理、上下文管理 | 捕获具体异常,不滥用 bare except |
| with语句 | 资源管理 | 文件、锁等资源使用with语句 |
| 推导式 | 简洁、高效 | 简单逻辑用推导式,复杂逻辑用普通循环 |
| match/case | 模式匹配(Python 3.10+) | 替代复杂的if/elif链 |