在实际编程中,代码并不总是按照从上到下的顺序逐行执行。很多时候,我们需要根据不同的条件选择执行不同的代码路径,或者需要重复执行某段代码。Python 提供了丰富的流程控制语句来满足这些需求。本章将深入介绍分支结构、循环结构以及相关的控制语句,帮助读者编写出逻辑清晰、功能强大的程序。
3.1 分支结构
分支结构允许程序根据条件的真假来选择执行不同的代码块。Python 中使用 if、elif 和 else 关键字实现分支。
3.1.1 单分支 if 语句
if 语句是最基本的条件判断结构,其语法格式如下:
python
if 条件:
代码块
注意:Python 靠代码缩进来识别代码范围,所以条件成立时要执行的代码前,必须加空格,且同一个代码块中的所有代码需保持统一的缩进。
当条件表达式的结果为 True 时,执行缩进的代码块;否则跳过该代码块。需要注意的是,条件后面必须跟一个冒号,代码块必须缩进(通常使用4个空格)。
示例1:检查数字是否为正数
python
num = 10
if num > 0:
print(f"{num} 是一个正数")
示例2:简单的登录验证
python
username = "admin"
if username == "admin":
print("欢迎管理员登录")
3.1.2 双分支 if-else 语句
当需要在条件为真和为假时执行不同的操作,可以使用 if-else 结构:
python
if 条件:
代码块1
else:
代码块2
示例1:判断奇偶性
python
number = 7
if number % 2 == 0:
print(f"{number} 是偶数")
else:
print(f"{number} 是奇数")
示例2:根据年龄判断是否允许观影
python
age = 16
if age >= 18:
print("允许观看限制级影片")
else:
print("只允许观看普通影片")
3.1.3 多分支 if-elif-else 语句
当需要判断多个条件时,可以使用 elif(即 else if 的缩写)。elif 可以有任意多个,最后的 else 是可选的。
python
if 条件1:
代码块1
elif 条件2:
代码块2
elif 条件3:
代码块3
...
else:
代码块n
注意 :分支语句的各个分支为互斥关系,程序会从上到下依次判断条件,一旦某个条件为真,就执行对应的代码块,然后跳过整个 if-elif-else 结构。如果所有条件都为假,则执行 else 后的代码块(如果有)。
示例1:成绩等级评定
python
score = 76
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:根据温度给出穿衣建议
python
temp = 22
if temp > 30:
advice = "穿短袖,注意防暑"
elif temp > 20:
advice = "穿长袖,天气舒适"
elif temp > 10:
advice = "穿外套,小心着凉"
else:
advice = "穿棉袄,注意保暖"
print(advice)
3.1.4 嵌套 if 语句
在条件判断中,可以在一个分支内部再嵌入另一个 if 语句,形成嵌套结构。嵌套时需要注意缩进层次,同级的代码须有一致的缩进。
示例1:判断一个数是否为正数,如果是正数再判断是否为偶数
python
num = 8
if num > 0:
print(f"{num} 是正数")
if num % 2 == 0:
print(f"{num} 也是偶数")
else:
print(f"{num} 是奇数")
else:
print(f"{num} 不是正数")
示例2:模拟用户登录权限验证
python
username = "alice"
password = "123456"
if username == "alice":
if password == "123456":
print("登录成功,欢迎 alice")
else:
print("密码错误")
else:
print("用户名不存在")
3.1.5 条件表达式(三元运算符)
Python 还提供了一种简洁的条件表达式,也称为三元运算符,用于根据条件返回不同的值。语法格式为:
python
条件为真时的值 if 条件 else 条件为假时的值
示例1:获取两个数中的较大值
python
a, b = 10, 20
max_value = a if a > b else b
print(f"较大值是:{max_value}")
示例2:根据分数判断及格状态
python
score = 55
status = "及格" if score >= 60 else "不及格"
print(f"考试状态:{status}")
3.1.6 match 语句(Python 3.10+)
从 Python 3.10 开始,引入了 match 语句,也称为"结构化模式匹配"。它类似于其他语言中的 switch-case 语句,但功能更强大,支持匹配多种模式(如字面量、变量、序列、映射等)。match 语句可以让代码在处理多个分支时更加清晰和简洁。
基本语法:
python
match 表达式:
case 模式1:
代码块1
case 模式2:
代码块2
...
case _:
代码块n # _ 是通配符,匹配任意值
match 后的表达式会被求值,然后从上到下与每个 case 后的模式进行匹配。一旦匹配成功,就执行对应的代码块,然后退出 match 语句(不需要显式 break)。如果没有任何模式匹配,且提供了 case _(通配符),则执行该分支;否则不执行任何操作。
示例1:匹配字面量
python
status_code = 404
match status_code:
case 200:
print("请求成功")
case 404:
print("资源未找到")
case 500:
print("服务器内部错误")
case _:
print("未知状态码")
# 输出:资源未找到
示例2:使用 | 匹配多个模式
可以在一个 case 中匹配多个值,用 | 分隔。
python
day = "周六"
match day:
case "周一" | "周二" | "周三" | "周四" | "周五":
print("工作日")
case "周六" | "周日":
print("周末")
case _:
print("无效的星期")
# 输出:周末
示例3:匹配序列(如列表、元组)
python
point = (0, 5)
match point:
case (0, 0):
print("原点")
case (0, y):
print(f"点在 y 轴上,y = {y}")
case (x, 0):
print(f"点在 x 轴上,x = {x}")
case (x, y):
print(f"点坐标为 ({x}, {y})")
case _:
print("不是二维点")
# 输出:点在 y 轴上,y = 5
这里的 x、y 是变量,会自动绑定到匹配到的值。
示例4:使用 if 守卫
可以在 case 后添加 if 条件来进一步限制匹配。
python
command = "move"
x = 10
match command:
case "move" if x > 0:
print(f"向右移动 {x} 步")
case "move":
print("不移动")
case _:
print("其他指令")
# 输出:向右移动 10 步
示例5:匹配字典(映射)
python
data = {"name": "张三", "age": 18}
match data:
case {"name": name, "age": age}:
print(f"姓名:{name},年龄:{age}")
case {"name": name}:
print(f"姓名:{name},年龄未知")
case _:
print("数据格式错误")
# 输出:姓名:张三,年龄:18
示例6:匹配对象(类实例)
match 也可以匹配特定类的实例,并提取属性。
python
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
p = Point(3, 4)
match p:
case Point(x=0, y=0):
print("原点")
case Point(x=x, y=y):
print(f"点坐标为 ({x}, {y})")
# 输出:点坐标为 (3, 4)
注意 :match 语句是 Python 3.10 的新特性,如果你的 Python 版本较低,则无法使用。但在新项目中,它能让代码更加优雅。
3.2 循环结构
循环结构用于重复执行某段代码,直到满足特定条件为止。Python 提供了两种主要循环:while 循环和 for 循环。
3.2.1 while 循环
while 循环在条件为真时反复执行代码块。其基本语法如下:
python
while 条件:
循环体
每次执行循环体前都会检查条件,如果条件为 True,则执行循环体;否则退出循环。如果条件永远为真,则会形成无限循环,通常需要配合 break 退出。
基本用法
示例1:计算 1 到 100 的和
python
total = 0
i = 1
while i <= 100:
total += i
i += 1
print("1 到 100 的和为:", total)
示例2:倒计时
python
countdown = 5
while countdown > 0:
print(f"倒计时:{countdown}")
countdown -= 1
print("时间到!")
while 循环与 else 子句
Python 的循环(包括 while 和 for)可以附带一个 else 子句,该子句在循环正常结束 (即没有被 break 中断)时执行。
示例:查找列表中是否存在负数
python
numbers = [3, 5, 7, -1, 9]
i = 0
while i < len(numbers):
if numbers[i] < 0:
print("发现负数,停止查找")
break
i += 1
else:
print("列表中没有负数")
由于列表中存在负数,break 触发,else 块不会执行。如果列表中没有负数,循环正常结束后会执行 else 块。
无限循环
无限循环通常用于需要一直运行直到满足某个条件才退出的场景,比如服务器监听、游戏主循环等。使用 while True 配合 break 实现。
示例:简单的命令解释器
python
while True:
command = input("请输入指令(输入 'exit' 退出):")
if command == 'exit':
print("程序结束")
break
elif command == 'hello':
print("你好!")
else:
print(f"未知指令:{command}")
3.2.2 for 循环
for 循环通常用于遍历可迭代对象。在 Python 中,对象 是数据的抽象表示,几乎所有的数据都是对象,比如数字 10、字符串 "hello"、列表 [1,2,3] 等。如果一个对象可以被遍历 (即可以依次取出其中的每一个元素),那么它就是可迭代对象 。例如字符串可以逐个取出字符,列表可以逐个取出元素,由 range() 生成的整数序列也是可迭代对象。
其基本语法为:
python
for 变量 in 可迭代对象:
循环体
在 for 循环中,变量 会在每次迭代时被赋值为可迭代对象中的下一个元素,然后执行循环体。如果变量在 for 循环之前没有被定义,这个变量会在 for 语句中隐式定义(即不需要用户自己定义,编译器自动定义),它的作用范围是当前循环体或全局作用域(取决于循环所在的位置)。循环结束后,该变量仍然存在,并保留最后一次迭代的值。
python
for ch in "ABC":
print(ch)
print("循环结束后 ch =", ch) # 输出 C
遍历字符串
示例:遍历字符串
python
word = "Python"
for ch in word:
print(ch, end='-') # 输出 P-y-t-h-o-n-
注意 :print(ch, end='-') 中的 end='-' 表示每次打印后不换行,而是以 - 结尾。默认情况下 print() 会在输出后自动换行,通过指定 end 参数可以改变这一行为,使得所有字符打印在同一行,并用 - 分隔。
遍历列表
列表是用方括号 [] 括起来的一组数据,可以包含任意类型的元素。例如:
python
cities = ["北京", "上海", "广州", "深圳"] # 这是一个列表
for city in cities:
print(f"{city} 是中国的一线城市")
遍历元组
元组与列表类似,但使用圆括号 () 表示,且元组一旦创建就不能修改(不可变)。元组也是可迭代对象,可以用 for 遍历。例如:
python
point = (10, 20) # 这是一个元组,表示坐标
for coord in point:
print(coord) # 依次输出 10 和 20
关于列表和元组的更多细节,将在后续章节中详细讲解。
range() 函数
range() 用于生成一个整数序列,常与 for 循环配合使用。其常见用法:
range(stop):生成从 0 到 stop-1 的整数。range(start, stop):生成从 start 到 stop-1 的整数。range(start, stop, step):生成从 start 到 stop-1,步长为 step 的整数。
示例1:输出 0~9
python
for i in range(10):
print(i, end=' ') # 0 1 2 3 4 5 6 7 8 9
示例2:输出 5~15 的奇数
python
for i in range(5, 16, 2):
print(i, end=' ') # 5 7 9 11 13 15
示例3:倒序输出 10~1
python
for i in range(10, 0, -1):
print(i, end=' ') # 10 9 8 7 6 5 4 3 2 1
循环嵌套
循环可以嵌套使用,即在一个循环内部再包含另一个循环。常用于处理二维数据结构或生成表格数据。
示例:打印乘法表
python
for i in range(1, 10):
for j in range(1, i + 1):
print(f"{j}×{i}={i * j:2}", end=" ")
print()
输出:
plain
1×1= 1
1×2= 2 2×2= 4
1×3= 3 2×3= 6 3×3= 9
1×4= 4 2×4= 8 3×4=12 4×4=16
...
3.2.3 循环控制语句
Python 提供了 break、continue 和 pass 来控制循环的执行流程。
break 语句
break 用于立即终止当前循环(无论是否还有未迭代的元素),跳出循环体。
示例:查找第一个能被 7 整除的数
python
numbers = [3, 8, 14, 25, 21, 30]
for num in numbers:
if num % 7 == 0:
print(f"找到第一个能被7整除的数:{num}")
break
continue 语句
continue 用于跳过当前迭代的剩余代码,直接进入下一次循环。
示例:输出 1~10 中不能被 3 整除的数
python
for i in range(1, 11):
if i % 3 == 0:
continue
print(i, end=' ') # 1 2 4 5 7 8 10
pass 语句
pass 是一个空操作语句,它什么也不做,通常用作占位符,在语法上需要语句但逻辑上尚未实现的地方使用。
示例:预留函数实现
python
def my_function():
pass # 将来在这里实现具体功能
3.3 辅助函数
Python 提供了一些内置函数,可以极大地简化循环的编写,特别是在需要索引或并行遍历时。
3.3.1 enumerate() 函数
enumerate() 用于将一个可迭代对象转换为索引和值的元组序列,常用于需要同时获取元素及其索引的场景。语法为:
python
enumerate(iterable, start=0) # start 指定索引起始值,默认为 0
示例1:输出带行号的文本
python
lines = ["第一行", "第二行", "第三行"]
for idx, line in enumerate(lines, start=1):
print(f"{idx}: {line}")
输出:
plain
1: 第一行
2: 第二行
3: 第三行
示例2:查找列表中最大值的索引
python
nums = [4, 7, 2, 9, 5]
max_value = max(nums)
for i, v in enumerate(nums):
if v == max_value:
print(f"最大值 {max_value} 的索引是 {i}")
3.3.2 zip() 函数
zip() 用于将多个可迭代对象"打包"成元组,然后返回这些元组组成的迭代器。常用于并行遍历多个序列。语法为:
python
zip(iterable1, iterable2, ...)
示例1:合并两个列表
python
names = ["赵一", "钱二", "孙三"]
ages = [20, 21, 22]
for name, age in zip(names, ages):
print(f"{name} 今年 {age} 岁")
示例2:将三个列表组合成字典
python
keys = ["name", "age", "city"]
values = ["Alice", 25, "北京"]
info = dict(zip(keys, values))
print(info) # {'name': 'Alice', 'age': 25, 'city': '北京'}
示例3:处理不等长序列
python
a = [1, 2, 3]
b = ['a', 'b', 'c', 'd']
for x, y in zip(a, b):
print(x, y) # 输出三行,第四个元素 'd' 被忽略
如果需要保留所有元素,可以使用 itertools.zip_longest()。
3.4 综合实例
实例1:猜数字游戏
程序随机生成一个 1~100 的整数,用户输入猜测的数字,程序提示"猜大了"、"猜小了"或"猜对了",并统计猜的次数。增加限制:最多猜 7 次,超过则失败。
python
import random
target = random.randint(1, 100)
max_attempts = 7
attempts = 0
print("欢迎参加猜数字游戏!")
print(f"你最多有 {max_attempts} 次机会。")
while attempts < max_attempts:
try:
guess = int(input("请输入你的猜测(1~100):"))
except ValueError:
print("请输入有效的整数!")
continue
attempts += 1
if guess < target:
print("猜小了!")
elif guess > target:
print("猜大了!")
else:
print(f"恭喜你,猜对了!数字是 {target}")
print(f"你用了 {attempts} 次机会。")
break
else:
print(f"很遗憾,机会用尽。正确的数字是 {target}。")
实例2:打印直角三角形图案
根据用户输入的行数,打印由星号组成的直角三角形。
python
rows = int(input("请输入行数:"))
# 左对齐直角三角形
for i in range(1, rows + 1):
print('*' * i)
# 右对齐直角三角形
for i in range(1, rows + 1):
spaces = ' ' * (rows - i)
stars = '*' * i
print(spaces + stars)
# 金字塔形
for i in range(1, rows + 1):
spaces = ' ' * (rows - i)
stars = '*' * (2 * i - 1)
print(spaces + stars)
实例3:统计字符串中各类字符的数量
用户输入一个字符串,程序统计其中大写字母、小写字母、数字和其他字符的个数。
python
text = input("请输入一个字符串:")
upper_count = lower_count = digit_count = other_count = 0
for ch in text:
if ch.isupper():
upper_count += 1
elif ch.islower():
lower_count += 1
elif ch.isdigit():
digit_count += 1
else:
other_count += 1
print(f"大写字母:{upper_count}")
print(f"小写字母:{lower_count}")
print(f"数字:{digit_count}")
print(f"其他字符:{other_count}")
实例4:模拟用户登录系统
设计一个简单的登录系统,用户有三次机会输入用户名和密码。预设正确的用户名和密码分别为 "admin" 和 "123456"。
python
correct_username = "admin"
correct_password = "123456"
max_attempts = 3
for attempt in range(1, max_attempts + 1):
print(f"第 {attempt} 次尝试(共 {max_attempts} 次)")
username = input("用户名:")
password = input("密码:")
if username == correct_username and password == correct_password:
print("登录成功!")
break
else:
if attempt < max_attempts:
print("用户名或密码错误,请重试。")
else:
print("尝试次数过多,账户已锁定。")
实例5:使用 zip 和 enumerate 生成带序号的学生成绩单
python
students = ["小明", "小红", "小刚", "小丽"]
scores = [88, 95, 78, 90]
print("序号\t姓名\t成绩")
for idx, (name, score) in enumerate(zip(students, scores), start=1):
print(f"{idx}\t{name}\t{score}")
输出:
plain
序号 姓名 成绩
1 小明 88
2 小红 95
3 小刚 78
4 小丽 90
3.5 总结
本章详细介绍了 Python 的流程控制语句,包括:
- 分支结构 :
if、if-else、if-elif-else、嵌套if、条件表达式(三元运算符)以及 Python 3.10+ 引入的match语句。 - 循环结构 :
while循环(含else子句)、for循环(遍历字符串、列表、元组等可迭代对象)、range()函数的使用。特别介绍了可迭代对象的概念以及for循环中变量的作用范围。 - 循环控制 :
break、continue、pass的作用与区别。 - 辅助函数 :
enumerate()和zip()在循环中的便捷应用。 - 综合实例:通过多个实际案例展示了流程控制语句的综合运用。
掌握这些语句是编写复杂程序的基础。在后续章节中,我们将学习函数、模块和文件操作等更高级的内容。希望读者能通过大量练习,熟练运用这些流程控制结构。