Python 基础语法(三):条件判断与分支结构

程序并不总是按照同一条路线执行。判断账号是否登录、成绩是否及格、文件是否存在,或者用户输入的内容是否有效,都需要根据条件决定接下来执行哪段代码。

思维导图

Python 使用 ifelifelse 编写条件分支。这一章会讲它们的基本写法、多个条件的判断顺序、真假值、条件嵌套和条件表达式,最后再介绍 Python 3.10 加入的 match case

一、最基本的 if 语句

if 用来判断一个条件是否成立。条件为真时,执行缩进后的代码;条件为假时,直接跳过这段代码。

python 复制代码
age = 20

if age >= 18:
    print("已经成年")

运行结果为:

txt 复制代码
已经成年

一条完整的 if 语句包含下面几部分:

python 复制代码
if 条件:
    条件成立时执行的代码
  • if 后面写条件表达式。
  • 条件后面要有冒号 :
  • 分支中的代码需要缩进,一般使用四个空格。

如果分支中有多条语句,它们需要保持相同的缩进:

python 复制代码
score = 85

if score >= 60:
    print("考试通过")
    print(f"当前成绩:{score}")

print("程序结束")

前两条 print() 属于 if 代码块,最后一条没有缩进,所以无论条件是否成立都会执行。

二、条件表达式

if 后面需要一个能够判断真假的表达式。比较运算是最常见的条件:

python 复制代码
temperature = 32

if temperature > 30:
    print("今天比较热")

常用的比较运算符如下:

运算符 含义 示例
== 等于 score == 100
!= 不等于 status != "closed"
> 大于 age > 18
< 小于 price < 100
>= 大于等于 score >= 60
<= 小于等于 count <= 10

这里容易把赋值运算符 = 和相等比较 == 写混:

python 复制代码
age = 20       # 把 20 赋值给 age
age == 20      # 判断 age 是否等于 20

if age = 20: 不是合法写法,会直接出现 SyntaxError

1. 连续比较

Python 支持连续比较,下面两种写法含义相同:

python 复制代码
score = 85

if score >= 60 and score <= 100:
    print("成绩有效,并且已经及格")
python 复制代码
if 60 <= score <= 100:
    print("成绩有效,并且已经及格")

连续比较更接近数学中的写法,不过只适合这种上下界连续判断。几个没有直接顺序关系的条件,还是应该使用逻辑运算符连接。

2. 成员判断

innot in 也可以直接作为条件:

python 复制代码
role = "editor"

if role in ("admin", "editor"):
    print("允许编辑")

字符串也支持成员判断:

python 复制代码
filename = "report.pdf"

if ".pdf" in filename:
    print("文件名中包含 .pdf")

如果要判断文件的扩展名,使用 endswith() 会更准确:

python 复制代码
if filename.lower().endswith(".pdf"):
    print("这是 PDF 文件")

3. 判断 None

判断变量是否为 None 时,一般使用 is

python 复制代码
result = None

if result is None:
    print("暂时没有结果")

判断普通数字、字符串和列表的内容时使用 ==,不要把 is 当成另一种相等比较。

三、使用 else 处理另一种情况

只有一个 if 时,条件不成立就不会执行分支中的代码。如果两种情况都需要处理,可以增加 else

python 复制代码
age = 16

if age >= 18:
    print("可以注册")
else:
    print("年龄未满 18 岁")

else 后面不写条件,因为它表示前面的条件不成立时剩下的情况。

下面这个例子判断一个数字是偶数还是奇数:

python 复制代码
number = 7

if number % 2 == 0:
    print("偶数")
else:
    print("奇数")

一个整数除以 2 的余数只可能是 01,所以这里使用 if else 可以覆盖全部情况。

四、使用 elif 判断多个分支

需要判断三种或者更多情况时,可以在 ifelse 之间加入 elif

python 复制代码
score = 85

if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
elif score >= 60:
    grade = "D"
else:
    grade = "E"

print(f"等级:{grade}")

Python 会从上到下检查这些条件。遇到第一个成立的分支以后,就执行对应代码,后面的分支不会继续判断。

在这个例子中,85 不满足 score >= 90,但是满足 score >= 80,所以结果为 B

1. 条件顺序会影响结果

如果把范围较宽的条件写在前面,后面的条件可能永远没有机会执行:

python 复制代码
score = 95

# 顺序错误
if score >= 60:
    grade = "及格"
elif score >= 90:
    grade = "优秀"

95 已经满足第一个条件,所以程序得到的是 及格。这种分段判断一般要按照从严格到宽松,或者从小到大的连续区间排列。

2. else 不是必需的

if 后面可以有多个 elif,最后不一定要写 else

python 复制代码
command = "start"

if command == "start":
    print("启动任务")
elif command == "stop":
    print("停止任务")
elif command == "status":
    print("查看状态")

如果 command 不属于这三种情况,程序就跳过整个分支。是否需要 else,要看剩余情况要不要处理。

五、多个 ifif elif 的区别

连续写多个 if 时,每个条件都会独立判断:

python 复制代码
score = 95

if score >= 60:
    print("考试通过")

if score >= 90:
    print("成绩优秀")

两个条件都成立,所以两句话都会输出。

改成 if elif 以后,只会执行第一个成立的分支:

python 复制代码
score = 95

if score >= 60:
    print("考试通过")
elif score >= 90:
    print("成绩优秀")

这次只会输出 考试通过。后面的 elif 并不会继续判断。

因此,如果几件事可以同时发生,就使用多个 if。如果多个分支互相排斥,只需要从中选择一个,就使用 if elif else

例如,一个订单可以同时满足会员优惠和满减活动,这两个条件可能要分别判断:

python 复制代码
price = 300
is_member = True

if is_member:
    price *= 0.9

if price >= 200:
    price -= 20

print(f"实付金额:{price:.2f} 元")

这里第二个判断使用的是会员折扣后的金额。实际业务中折扣顺序会影响结果,所以规则和执行顺序需要先确定清楚。

六、使用逻辑运算符组合条件

一个分支经常需要同时检查多个条件,可以使用 andornot

1. and

and 两边都为真时,整个条件才为真:

python 复制代码
age = 20
has_ticket = True

if age >= 18 and has_ticket:
    print("允许入场")

2. or

or 两边只要有一个为真,整个条件就为真:

python 复制代码
role = "editor"

if role == "admin" or role == "editor":
    print("允许修改内容")

判断一个变量是否等于多个候选值时,也可以使用成员判断,代码会更短:

python 复制代码
if role in ("admin", "editor"):
    print("允许修改内容")

下面这种写法是错误的:

python 复制代码
# 错误写法
if role == "admin" or "editor":
    print("允许修改内容")

非空字符串 "editor" 本身就是真值,所以这个条件几乎总会成立。

3. not

not 会把真假结果反过来:

python 复制代码
is_disabled = False

if not is_disabled:
    print("账号可以使用")

4. 运算优先级

not 的优先级高于 andand 又高于 or。条件比较长时,不要只依赖优先级,使用括号会更容易检查:

python 复制代码
age = 20
is_member = False
has_invitation = True

if age >= 18 and (is_member or has_invitation):
    print("允许参加活动")

七、Python 中的真值与假值

if 后面不一定要写比较表达式。Python 会把对象转换成布尔值,再决定条件是否成立。

下面这些值会被当成 False

  • False
  • None
  • 数字 00.00j
  • 空字符串 ""
  • 空列表 []
  • 空元组 ()
  • 空字典 {}
  • 空集合 set()

其他大多数对象会被当成 True

python 复制代码
name = "Ivan"

if name:
    print("姓名不为空")

上面的写法相当于:

python 复制代码
if name != "":
    print("姓名不为空")

判断列表是否有内容时也经常这样写:

python 复制代码
items = ["Python", "Java"]

if items:
    print("列表中有数据")
else:
    print("列表为空")

1. 字符串 "False" 仍然是真值

字符串里的文字不会自动变成布尔值:

python 复制代码
print(bool("False"))
print(bool("0"))
print(bool(""))

输出结果为:

txt 复制代码
True
True
False

前两个字符串中都有字符,所以结果是 True。读取配置或用户输入时,不能直接使用 bool(text) 解析文字形式的真假值,可以自己写出允许的内容:

python 复制代码
value = "false"

is_enabled = value.strip().lower() in ("true", "1", "yes", "on")
print(is_enabled)

2. None 和空值的含义不同

None 通常表示没有结果或者尚未设置,空字符串和空列表则表示有这个值,只是内容为空。在某些程序里它们可以使用相同的处理方式,但含义并不完全一样:

python 复制代码
result = None

if result is None:
    print("还没有查询")
elif not result:
    print("已经查询,但是结果为空")
else:
    print("查询到了内容")

八、短路计算

逻辑运算符会按照需要决定是否继续计算右侧表达式。

and 左侧已经为假时,整个结果一定为假,所以右侧不会执行:

python 复制代码
number = 0

if number != 0 and 10 / number > 2:
    print("条件成立")

由于 number != 0False10 / number 不会执行,因此不会出现除零错误。

or 左侧已经为真时,整个结果一定为真,右侧也不会执行:

python 复制代码
is_admin = True

if is_admin or check_permission():
    print("允许访问")

这里假设 check_permission() 是一个权限检查函数。is_admin 已经为真时,这个函数不会被调用。

短路计算可以避免不必要的操作,不过不要为了省几行代码,把有副作用的函数调用藏在很长的条件中。条件本身应该能够让人直接看懂。

九、嵌套条件判断

一个分支内部还可以继续写 if,这种结构称为嵌套条件:

python 复制代码
is_login = True
role = "admin"

if is_login:
    print("已经登录")

    if role == "admin":
        print("进入管理页面")
    else:
        print("进入普通用户页面")
else:
    print("请先登录")

内层代码需要再增加一级缩进。嵌套两三层还能看懂,层级继续增加以后,判断关系会变得很乱。

有些嵌套可以合并成一个条件:

python 复制代码
if is_login and role == "admin":
    print("进入管理页面")

不过这两种写法不一定完全等价。前一个例子还需要分别处理未登录和普通用户,合并以后只保留了管理员这一种情况。是否合并,要看每个分支是不是还有自己的处理逻辑。

十、提前结束,减少嵌套

在函数中遇到不满足条件的情况,可以使用 return 提前结束函数。这样通常比不断增加 else 更容易读:

python 复制代码
def get_discount_price(price, is_member):
    if price <= 0:
        return 0

    if not is_member:
        return price

    return price * 0.9

如果不提前返回,也可以写成:

python 复制代码
def get_discount_price(price, is_member):
    if price <= 0:
        result = 0
    else:
        if not is_member:
            result = price
        else:
            result = price * 0.9

    return result

第二种写法没有语法问题,但是多了一层嵌套。函数内容变长以后,提前处理异常情况和边界情况会更清楚。函数和 return 会在后面的章节中详细讲,这里先理解这种写法为什么能够减少层级。

十一、条件表达式

如果只是根据一个条件在两个值之间选择,可以使用条件表达式:

python 复制代码
age = 20
message = "成年" if age >= 18 else "未成年"

print(message)

它的基本结构是:

python 复制代码
条件成立时的值 if 条件 else 条件不成立时的值

条件表达式适合简单赋值。如果两个分支各有多条语句,还是使用普通的 if else

python 复制代码
score = 85

if score >= 60:
    print("考试通过")
    print(f"当前成绩:{score}")
else:
    print("考试未通过")
    print("需要参加补考")

不要连续嵌套多个条件表达式。虽然语法允许,但是读起来比普通分支更费劲。

十二、空代码块与 pass

Python 的代码块不能为空。如果暂时还没有想好分支中的内容,可以使用 pass 占位:

python 复制代码
status = "pending"

if status == "pending":
    pass
else:
    print("任务已经处理")

pass 不会执行任何操作,它只保证当前代码块在语法上完整。后面补上正式代码以后,应该把它删除。

十三、使用 match case 匹配固定分支

Python 3.10 加入了 match case。当程序需要根据同一个值匹配多个固定分支时,它有时会比一长串 elif 更清楚:

python 复制代码
command = "status"

match command:
    case "start":
        print("启动任务")
    case "stop":
        print("停止任务")
    case "status":
        print("查看状态")
    case _:
        print("未知命令")

case _ 用来接收前面都没有匹配到的情况,作用有点像 else

1. 同时匹配多个值

竖线 | 可以把几个候选值放在同一个分支:

python 复制代码
method = "GET"

match method:
    case "GET" | "HEAD":
        print("读取请求")
    case "POST" | "PUT":
        print("写入请求")
    case _:
        print("其他请求")

2. 解构序列

match case 还能按照数据结构匹配内容:

python 复制代码
point = (10, 0)

match point:
    case (0, 0):
        print("原点")
    case (x, 0):
        print(f"X 轴上的点:{x}")
    case (0, y):
        print(f"Y 轴上的点:{y}")
    case (x, y):
        print(f"普通坐标:{x}, {y}")

这里的 xy 会接收匹配位置上的值。它已经不只是其他语言中常见的 switch,还包含结构模式匹配的能力。

对于简单的真假条件和范围判断,if elif else 仍然更直接。match case 更适合同一个对象有多种固定形式,或者需要根据结构拆出数据的情况。

十四、综合示例:计算订单实付金额

下面的程序根据订单金额、会员状态和优惠码计算实付金额。为了方便查看条件执行顺序,例子没有把逻辑拆成函数:

python 复制代码
amount = float(input("请输入订单金额:"))
member_text = input("是否为会员(yes/no):").strip().lower()
coupon = input("请输入优惠码,没有则直接回车:").strip().upper()

if amount <= 0:
    print("订单金额必须大于 0")
else:
    is_member = member_text in ("yes", "y")

    if is_member:
        amount *= 0.9

    if coupon == "SAVE20" and amount >= 100:
        amount -= 20
    elif coupon:
        print("优惠码无效或者未达到使用金额")

    shipping_fee = 0 if amount >= 99 else 8
    total = amount + shipping_fee

    print(f"商品金额:{amount:.2f} 元")
    print(f"运费:{shipping_fee:.2f} 元")
    print(f"实付金额:{total:.2f} 元")

如果输入:

bash 复制代码
请输入订单金额:150
是否为会员(yes/no):yes
请输入优惠码,没有则直接回车:SAVE20

会员折扣后金额为 135 元,继续满足优惠码条件,再减去 20 元。由于最后金额仍然超过 99 元,所以免运费,输出结果为:

复制代码
商品金额:115.00 元
运费:0.00 元
实付金额:115.00 元

这个例子中会员折扣和优惠码可以同时生效,所以使用了两个独立的 if。优惠码无效和没有输入优惠码的处理又不同,因此第二个判断中使用了 elif coupon

十五、常见错误

1. 忘记写冒号

python 复制代码
# 错误写法
if score >= 60
    print("考试通过")

条件后面缺少冒号,会出现 SyntaxError

2. 缩进不一致

python 复制代码
# 错误写法
if score >= 60:
    print("考试通过")
  print("成绩有效")

同一个代码块必须保持相同缩进,不要混用不同数量的空格和制表符。

3. 把 = 写成判断条件

python 复制代码
# 错误写法
if status = "done":
    print("任务完成")

相等比较应该使用 ==

python 复制代码
if status == "done":
    print("任务完成")

4. elif 顺序写反

python 复制代码
score = 95

# 范围较宽的条件挡住了后面的分支
if score >= 60:
    print("及格")
elif score >= 90:
    print("优秀")

这类范围判断需要检查每一个边界值,尤其是 59608990100 这些刚好位于区间边缘的值。

5. 错误使用 or

python 复制代码
# 错误写法
if role == "admin" or "editor":
    print("允许访问")

应该完整比较两次,或者直接使用成员判断:

python 复制代码
if role == "admin" or role == "editor":
    print("允许访问")

if role in ("admin", "editor"):
    print("允许访问")

6. 把多个独立条件写成 elif

如果一个订单能够同时使用两项优惠,第二项就不能写成 elif,否则第一项成立以后,第二项不会继续判断。

7. 条件嵌套太深

嵌套层级太多时,可以把边界情况提前处理,或者把一部分判断拆成函数。不要为了追求代码行数少,把所有条件挤在一个表达式里。

十六、练习

练习一:判断数字

接收用户输入的整数,判断它是正数、负数还是零。

练习二:成绩等级

接收 0100 之间的成绩,按照下面的规则输出等级:

成绩范围 等级
90~100 A
80~89 B
70~79 C
60~69 D
0~59 E

输入不在 0100 范围内时,输出 成绩无效

练习三:闰年判断

接收一个年份。能够被 400 整除,或者能够被 4 整除但不能被 100 整除的年份是闰年。

练习四:简单登录判断

预设用户名和密码,接收用户输入。用户名和密码都正确时输出 登录成功;用户名不存在时输出 用户不存在;用户名正确但密码错误时输出 密码错误

练习五:票价计算

根据年龄计算票价:6 岁以下免费,6~17 岁半价,18~59 岁全价,60 岁及以上半价。再增加一个会员条件,会员可以在计算后的票价上继续打九折。

练习六:命令匹配

使用 match case 处理 startstopstatushelp 四个命令,其他输入统一输出 未知命令

这一章讲完以后,程序已经可以根据输入选择不同的执行路线。下一章会继续讲循环,包括 whileforrange()breakcontinue

相关推荐
用户019027581611 小时前
如何用 Python 算多只股票的相关性矩阵与组合波动率?
python
用户0332126663672 小时前
快速合并 Word 文档【Python 指南】
python
威联通网络存储2 小时前
TS-h987XU-RP 在化工制造批次数据场景的部署
python·制造
m0_547486662 小时前
《Python爬虫大数据采集与挖掘》全套PPT课件2026
爬虫·python·powerpoint
CV山月2 小时前
《DPO 算法详解:不训练奖励模型,如何让大模型直接学会人类偏好?》
人工智能·经验分享·python·大模型·强化学习·研究生
ctlover2 小时前
网络编程和多线程
开发语言·网络·python
Mr_liu_6662 小时前
ns3-gym例子解析_基础例子与wifi例子_DQN(3)
开发语言·c++·python·dqn·ns3
weixin_440730502 小时前
playwright实战-渠道应用操作
开发语言·前端·python
asdzx672 小时前
Python 解析 Excel 数据、图片与图表的实现方案
python·excel