4、分支和循环:if判断语句、运算符、if-else语句、while循环、for循环、break、continue

写代码说白了就是让计算机做决策、重复干活。没有分支和循环,程序就是一条道走到黑,毫无灵活性。这一章我们就把 Python 里最核心的控制流讲透。

本章核心脉络:判断条件 → 分支执行 → 循环迭代 → 循环控制。掌握了这四步,你就能写出有「脑子」的程序了。

分支与循环知识体系 控制流 分支结构 循环结构 if 判断 if-else 运算符 while 循环 for 循环 break continue 核心要点 • 分支:根据条件真假决定走哪条路 • 循环:重复执行某段代码直到条件不满足 • break/continue:精细控制循环节奏

4.1 运算符:判断的基石

写判断之前,得先搞清楚 Python 里有哪些运算符。说白了,运算符就是用来比较和计算的符号。

类别 运算符 说明 示例
比较运算符 == != > < >= <= 比较两个值,返回 True/False 5 > 3 → True
逻辑运算符 and or not 组合多个条件 a > 0 and b < 10
成员运算符 in not in 检查是否在序列中 "py" in "python"
身份运算符 is is not 检查是否是同一个对象 a is None

我的小习惯:判断是否为空时,我更喜欢用 if not lst: 而不是 if len(lst) == 0:。前者更 Pythonic,读起来也自然。

4.2 if 判断语句:最简单的分支

if 语句就是「如果……就……」。语法很简单,但缩进是命根子。

# 基础语法
if 条件:
    执行代码

# 实际例子
age = 18
if age >= 18:
    print("已成年,可以注册")

我在项目中遇到过一个问题:同事把条件写成了 if age = 18:,少写一个等号,直接赋值了。Python 里赋值表达式不会报错,但结果永远为 True。嗯,这种 bug 最难查。

4.3 if-else 语句:两条路

有 if 没 else,就像有白天没黑夜。if-else 让你在条件为假时走另一条路。

score = 75
if score >= 60:
    print("及格了")
else:
    print("不及格,需要补考")

你想想看,如果只有 if,不及格的情况就没人管了。程序会静悄悄地什么都不做,用户还以为系统坏了。

4.3.1 if-elif-else:多条路

现实世界不是非黑即白的。成绩有优、良、中、差,这时候就需要 elif 登场。

score = 85
if score >= 90:
    grade = "优秀"
elif score >= 80:
    grade = "良好"
elif score >= 70:
    grade = "中等"
elif score >= 60:
    grade = "及格"
else:
    grade = "不及格"
print(f"等级:{grade}")

我曾经踩过的坑:写 elif 时把条件顺序搞反了。比如先判断 score >= 60 再判断 score >= 90,结果 95 分的人永远进不了「优秀」分支。记住:范围判断要从窄到宽,或者从大到小。

4.4 while 循环:条件驱动

while 循环就是「只要条件成立,就一直做」。它适合你不知道要循环多少次的情况。

# 猜数字游戏
secret = 7
guess = None

while guess != secret:
    guess = int(input("猜一个数字(1-10):"))
    if guess < secret:
        print("小了")
    elif guess > secret:
        print("大了")
print("猜对了!")

这里有个关键点:循环体内必须改变条件相关的变量,否则会变成死循环。我见过有人写 while True: 然后忘了写 break,程序直接跑死。

4.5 for 循环:遍历驱动

for 循环用来遍历一个可迭代对象。说白了,就是挨个拿数据。

# 遍历列表
packages = ["requests", "flask", "django", "numpy"]
for pkg in packages:
    print(f"正在安装:{pkg}")

# 遍历字典
config = {"host": "localhost", "port": 8080}
for key, value in config.items():
    print(f"{key} = {value}")

# 配合 range
for i in range(5):
    print(f"第 {i+1} 次尝试")

我的经验:处理包依赖时,我经常用 for 循环遍历 requirements.txt 的每一行,然后逐个检查版本号。配合 enumerate 还能拿到行号,方便定位问题。

4.6 break 和 continue:循环的刹车和油门

这两个关键字是循环的精细控制器。break 是急刹车,直接跳出整个循环。continue 是跳过当前这一轮,继续下一轮。

4.6.1 break:提前终止

# 找到第一个满足条件的就停
numbers = [3, 7, 2, 9, 4, 6]
for num in numbers:
    if num > 5:
        print(f"找到第一个大于5的数:{num}")
        break
# 输出:找到第一个大于5的数:7

4.6.2 continue:跳过本轮

# 只处理符合条件的元素
for i in range(10):
    if i % 2 == 0:
        continue  # 偶数跳过
    print(f"奇数:{i}")
# 输出:1 3 5 7 9

实用技巧:在包依赖检查中,我常用 continue 跳过已安装的包,只处理需要更新的。这样日志干净,效率也高。

4.7 综合实战:包版本检查器

把这一章的知识串起来,写一个简单的包版本检查器。

# 模拟的已安装包列表
installed = [
    {"name": "requests", "version": "2.25.1"},
    {"name": "flask", "version": "2.0.0"},
    {"name": "django", "version": "3.2.0"},
]

# 需要检查的包和最低版本要求
required = {
    "requests": "2.26.0",
    "flask": "2.0.0",
    "numpy": "1.21.0",
}

def compare_versions(v1, v2):
    """简单版本比较,返回 True 如果 v1 >= v2"""
    parts1 = [int(x) for x in v1.split(".")]
    parts2 = [int(x) for x in v2.split(".")]
    return parts1 >= parts2

print("开始版本检查...")
for pkg_name, min_version in required.items():
    found = False
    for inst in installed:
        if inst["name"] == pkg_name:
            found = True
            if compare_versions(inst["version"], min_version):
                print(f"✓ {pkg_name} {inst['version']} 满足要求")
            else:
                print(f"✗ {pkg_name} {inst['version']} 需要升级到 {min_version}")
            break
    if not found:
        print(f"✗ {pkg_name} 未安装,需要安装 >= {min_version}")

print("检查完成")

这段代码用了 for 循环遍历依赖列表,if-else 做版本判断,break 在找到包后提前跳出内层循环。你想想看,如果没有 break,同一个包会被重复检查多次,效率就低了。

核心总结:分支让程序有判断力,循环让程序有耐力。两者结合,就能写出处理真实业务逻辑的代码。写的时候多想想边界条件——空列表、None 值、异常输入,这些我在项目里都吃过亏。