资讯详情

Python分支结构详解:if、elif、else与嵌套用法从入门到实战

📅 2026/10/20 15:15:17 | 华诺云谱 👁 阅读
Python分支结构详解:if、elif、else与嵌套用法从入门到实战
写代码最绕不开的一步就是让程序学会“看情况办事”。很多刚接触 Python 的朋友能把变量、数据类型、运算符背得滚瓜烂熟一遇到“如果……就……否则……”这种需求就开始堆 if代码越写越长逻辑却越来越乱。这篇文章就把 Python 分支结构相关的六块内容一次性讲透顺序结构、单分支、双分支、多分支、分支嵌套还有那个经常被忽视的 pass 关键字。适合刚学完基础语法、准备迈入流程控制大门的读者也适合写了一阵子代码但碰到判断逻辑就头大的同学。我会把语法规则、底层逻辑、实际案例以及我平时写判断时踩过的坑都拆开来讲保证你能直接照着写。这篇内容不打算按教科书的路子平铺直叙而是按照“从最简单到最复杂、从语法到实战”的顺序来。你会发现分支结构本质上不是语法问题而是思维问题——先想清楚有几条路再动手写代码比反过来效率高得多。1. 程序不能只会“直行”顺序结构的地位与局限1.1 逐行执行的“默认模式”如果你写一个最简单的脚本里面有三行代码Python 解释器会从上到下、一行一行地执行每行只执行一次执行完最后一行程序就结束。这种结构就叫顺序结构它是所有程序的地基你之前写的每一个print、每一个赋值语句其实都生活在顺序结构的框架里。user_name 小林 print(欢迎来到示例商城) print(当前登录用户 user_name) total_price 100 print(购物车金额 str(total_price))这段代码没有任何拐弯执行结果完全可以预测。对初学者来说顺序结构没什么好“学”的它更像是默认规则。但你得意识到顺序结构最大的问题是它无法表达“如果”和“否则”。现实业务里几乎没有哪个功能能靠一路直行完成。1.2 为什么现实业务到处都需要岔路我经常跟刚入门的朋友打比方顺序结构是一条没有红绿灯的马路而分支结构就是路口的红绿灯和指示牌。程序没有分支就相当于一辆永远直行的车遇到路口不拐弯遇人也不刹车。举几个每天都能遇到的例子登录页面账号密码输入正确进首页错误弹提示这就是典型的分支。购物车结算满 199 减 50不满就原价这也是分支。成绩查询90 分以上是优秀60 到 90 是及格60 以下是挂科这还是分支。可以这么说分支结构是程序具备“决策能力”的起点。顺序结构解决的是“按步骤把事情做完”的问题分支结构解决的是“在不同条件下做不同事情”的问题。你在写任何带判断功能的代码时脑子里要有一个意识先画清楚有几条路、每条路在什么条件下走然后用 if 体系去实现它。2. 单分支 if条件成立才执行的“单行道”2.1 语法骨架与缩进约定单分支是最简单的判断结构语法特别直白if 条件: 条件成立时要执行的代码需要注意两点。第一条件后面必须跟英文冒号很多新手第一次写都会把冒号漏掉。第二条件成立时要执行的代码必须缩进通常用 4 个空格。缩进在别的语言里只是代码风格问题在 Python 里是语法的一部分缩进不对程序直接报错。看一个真实业务场景。你在做一个商品下单功能库存不足的时候要提示用户stock 3 buy_count 5 if stock buy_count: print(库存充足正在生成订单...) print(下单成功)这里stock buy_count就是条件当库存大于等于购买数量时两个print都会执行。如果库存不够程序就什么都不做直接跳过去。2.2 把“真”和“假”搞清楚if后面跟的条件本质上是需要一个真值或假值。除了常见的比较运算大于、小于、等于会产生布尔值Python 里很多值本身就会被直接当作“真”或“假”来用。会被当作“假”的0、0.0、空字符串、[]空列表、()空元组、{}空字典、None。其余的绝大多数值都会被当作“真”。这个特性在业务代码里特别好用。比如你从接口拿到一个列表想知道它是不是有数据不需要写if len(item_list) 0直接写if item_list即可代码更简洁而且不容易漏判。item_list [] if item_list: print(有商品数据) else: print(商品数据为空)注意这里为了让例子完整我用了else它属于双分支的范畴后面马上会讲。你现在只需要理解条件判断看的是“真假”而不仅仅是“是否相等”。2.3 单分支最容易翻车的三个位置根据我带人写代码的经验单分支的错基本集中在三个地方。第一个是冒号丢失。if stock buy_count后面没有冒号解释器立刻报SyntaxError这种错误特别容易发生在手打代码的时候。我建议你一开始就养成习惯写完if 条件后条件反射般地敲冒号、回车、缩进一气呵成。第二个是缩进不一致。有些朋友会用 2 个空格有些地方用 4 个或者 tab 和空格混用。Python 2 时代 tab 和空格混用经常会出诡异的问题Python 3 里虽然报错更明确但依然不该混用。我的习惯是全局统一 4 个空格并且让编辑器把 tab 自动转换成空格。第三个是把写成。if status 1这种写法在 Python 里不是条件判断而是赋值语句解释器会在条件位置直接报语法错误。这个问题看起来低级但频率真的很高尤其是从 C 或 Java 转过来的人更容易手滑。3. 双分支 if-else给每条判断都找个“退路”3.1 双分支是互补的不是两个单分支的拼接单分支有个问题条件不成立时程序什么都不做。但很多场景下条件不成立时也得有反应比如登录失败要提示密码错误库存不足要提示购买失败。这时候就需要if-else。if 条件: 条件成立执行 else: 条件不成立执行关键是理解if和else的互斥性条件只会产生一个真值或假值所以两个分支中仅有一个会执行不会同时执行。这种“非此即彼”的关系就是双分支结构的核心。有些初学者会把双分支写成两个独立的单分支age 17 if age 18: print(已成年) if age 18: print(未成年)这样写虽然也能工作但问题是程序要判断两次而且如果将来条件变了很容易出现两边都漏掉的情况。更重要的是从语义上讲这不是“双分支”而是两条无关的单行道。用if-else表达会更清楚要么成人要么未成年没有第三种情况。3.2 一个完整的登录校验 Demo看一个更有代入感的例子。假设你要做一个命令行版的登录校验input_password input(请输入密码) correct_password py123 if input_password correct_password: print(验证通过正在进入系统...) print(欢迎回来管理员) else: print(密码错误请重新输入) print(连续错误 5 次将锁定账号)这里的效果是密码对走if分支密码错走else分支。两条分支都有输出用户无论输对输错都有反馈。这就是双分支的价值——它保证了程序在任何情况下都有响应不会“卡死在半路”。3.3 关于 else 是否省略的个人习惯写了几年代码后我对else有个私人习惯能明确配对的逻辑我都会写 else即使 else 里只有一行注释。比如下面这段if user.is_active: send_welcome_email() else: # 账号未激活暂不发送邮件 pass这个else里虽然什么都没干但它的存在告诉阅读代码的人我考虑过账号未激活的情况只是决定不处理。这种“显式说明”能让人快速理解意图避免后来的人疑惑“是不是这里漏了逻辑”。当然某些场景下省略else更清爽比如前置校验失败就立刻结束函数的时候。这个度得看语境但原则是不要为了让代码短而牺牲可读性。4. 多分支 elif让程序学会“对号入座”4.1 为什么一堆 if 不是“多分支”现实里经常遇到超过两种情况判断。比如一个成绩评级系统90 以上优秀80-90 良好60-80 及格60 以下不及格。如果你用多个 if 来写score 85 if score 90: print(优秀) if score 80: print(良好) if score 60: print(及格) if score 60: print(不及格)这段代码执行完后会打印出“良好”和“及格”两行显然不对。原因就在于多个if彼此独立每个都会判断一次条件可以同时成立。而elif把多个判断串成了“一条链”只要某个条件成立整条链就结束后面的分支不会再检查。score 85 if score 90: print(优秀) elif score 80: print(良好) elif score 60: print(及格) else: print(不及格)这次只输出“良好”。从第一个条件开始依次往下命中即停这就是多分支的真正语义。这个区别是初学者最容易踩的坑之一面试也常会问到。4.2 多分支的“短路”特性上面那段代码体现了一个重要特性elif是“短路”的。一旦某个条件成立后续所有elif和else都不会再执行。这个特性在业务场景里可以省掉很多麻烦。比如你要给不同等级的用户发放不同的优惠券等级从上到下由高到低level 黄金会员 if level 钻石会员: coupon 100 elif level 黄金会员: coupon 50 elif level 白银会员: coupon 20 else: coupon 0 print(可领取优惠券金额 str(coupon))这里黄金会员会在第二个条件处命中后面的条件就不会再判断了。用elif你不需要在每一个条件里显式写and level ! 钻石会员因为短路机制已经帮你处理了互斥关系。4.3 区间边界画一条数轴再动手多分支里最难受的问题倒不是语法而是边界怎么算。还是看分数例子从 90、80、60 三个“分界点”出发可以画出四条区间90、[80, 90)、[60, 80)、60。我强烈建议在写多分支之前先在纸上画一条数轴把每个分界点标出来再决定每个条件用还是。实际业务里边界错一位的后果有时候很严重。比如会员折扣活动里满 300 减 80满 500 减 150两个档位。如果写成if amount 500: discount 150 elif amount 300: discount 80 else: discount 0这是对的。但如果你把顺序写反先判断 300 再判断 500那 600 块的订单就只能减 80 了。所以记住一个核心原则区间条件要从严格到宽松或者从上限到下限顺序不能乱。我在写这类逻辑时还会特意准备几条刚好等于边界值的测试数据比如 300、500、299、501确保每一档都被验证到。5. 分支嵌套复杂业务里的“迷宫导航”5.1 嵌套的场景长什么样有些业务不是一条链能解决的而是“先判断大类再在大类里判断小类”。最典型的例子是权限控制用户先得登录登录了再看角色角色对了再看能不能执行某个操作。用代码表示就是分支里套分支也就是嵌套。is_login True role admin action delete if is_login: if role admin: if action delete: print(允许删除) else: print(该操作不在权限范围内) else: print(非管理员不能执行删除) else: print(请先登录)这个三层嵌套逻辑是清晰了但肉眼读起来已经有点累。缩进一层层加深代码往右偏得厉害。所以嵌套不是不能写而是要控制深度。5.2 控制嵌套深度与可读性我自己的经验是嵌套尽量控制在三层以内。超过三层读代码的人大概率得拿一支笔出来标记哪一层是哪个条件。那怎么压深度有两个常用技巧。第一个技巧是“提前返回”。上面的权限例子可以这样改is_login True role admin action delete if not is_login: print(请先登录) else: if role ! admin: print(非管理员不能执行删除) else: if action delete: print(允许删除) else: print(该操作不在权限范围内)等等这个写法虽然逻辑等价但嵌套并没有变少。真正有效的方式是引入函数和提前 returndef check_permission(is_login, role, action): if not is_login: print(请先登录) return if role ! admin: print(非管理员不能执行删除) return if action delete: print(允许删除) return print(该操作不在权限范围内)这里的嵌套完全消失了变成了三个平级的单分支。每个条件不满足就立刻结束函数不再往里钻。这种写法叫“卫语句”是我在处理权限、校验类逻辑时非常喜欢的方式。第二个技巧是用逻辑运算符把条件拍平。有些嵌套其实是在表达“多个条件同时满足才做事”这种情况可以直接写到同一个if里if is_login and role admin and action delete: print(允许删除) else: print(无权限或操作不允许)这样可读性反而更高。但要注意逻辑运算符的适合场景是“条件之间是并列关系”。如果判断存在明显的先后次序比如先判断用户是否登录、再判断角色权限那还是拆成多段更贴合业务直觉。5.3 嵌套和复合条件怎么选我给一个简单标准供你参考如果每个条件对应不同的输出用嵌套配合卫语句如果条件可以合并成一个整体判断用and和or拍平。不要为了追求“一行”而把所有条件硬塞进一个表达式也不要为了展示嵌套技巧而故意多套几层。代码是写给人看的顺便让机器执行。6. pass 关键字先留位再填空6.1 语法上不允许“空手道”有一个问题初学者经常遇到写了一个if分支但暂时还没想好逻辑要做什么只想先搭个架子让程序能跑起来。这时候如果你直接什么都不写if user.age 18: # 还没想好Python 解释器会直接报IndentationError: expected an indented block。因为冒号下面必须有一个缩进的代码块这个代码块不能为空。这时候pass就出场了。它是一个空语句什么都不执行只用来保证语法正确。if user.age 18: pass程序运行到这一行会直接跳过什么都不发生。这就是pass最常见的用法占位。6.2 pass、continue、break、return 的分工pass、continue、break、return这四个关键字在流程控制里各有各的位置很多初学者容易搞混我用一个表格来说明。关键字作用常用场景pass什么都不做只占位分支或函数暂时没实现continue跳过本次循环剩余代码进入下一次循环循环里过滤不符合条件的元素break立即结束整个循环找到目标后提前终止循环return退出函数并返回结果函数中结束当前执行路径特别注意pass和continue在循环里看起来都是“什么都没发生”但语义完全不同。pass不改变执行流它继续执行后面的代码continue则会让当前这轮循环到此为止直接跳回循环头部。for i in range(5): if i 3: pass print(i) # 输出0 1 2 3 4 for i in range(5): if i 3: continue print(i) # 输出0 1 2 46.3 用 pass 规划代码骨架pass最实用的场景是“自顶向下”写代码。你在开发一个功能前先把整体框架搭出来每个模块先用pass占住位置然后逐个填空。这样写的好处是你可以先把业务流程跑通再补充细节不会出现“框架没搭完程序根本跑不起来”的尴尬。def process_order(order): 处理订单的主流程 if order is None: pass # 后续增加参数校验 else: pass # 后续增加订单状态判断 if __name__ __main__: pass # 后续增加一整套测试调用这种骨架式写法在团队协作里尤其好用。代码评审时你一眼就能看出哪些逻辑已经填完、哪些还在施工中。比起用注释写“TODO”pass至少保证代码是可执行的。7. 把这些串起来一个会员折扣系统的完整实现7.1 业务需求拆解这一章把前面的内容全部串起来做一个简单的会员折扣系统。业务需求如下用户输入购物金额和会员等级。会员等级只有三种普通用户、黄金会员、钻石会员。普通用户不打折黄金会员满 300 减 50钻石会员无论金额多少都打 8 折但折扣上限是 200 元。金额必须大于 0否则提示输入错误。这个需求看起来不复杂但它把顺序结构、单分支、双分支、多分支、嵌套、占位全用上了。真正考验人的不是语法而是怎么把业务拆成判断链。7.2 代码实现与每段解释amount float(input(请输入购物金额)) member_level input(请输入会员等级普通/黄金/钻石) if amount 0: print(金额必须大于0) else: if member_level 黄金会员: if amount 300: final_price amount - 50 print(黄金会员满300减50实付 str(final_price)) else: print(未达到满减门槛实付 str(amount)) elif member_level 钻石会员: discount amount * 0.2 if discount 200: final_price amount - 200 print(钻石会员8折折扣上限200实付 str(final_price)) else: final_price amount - discount print(钻石会员8折实付 str(final_price)) elif member_level 普通用户: print(普通用户无折扣实付 str(amount)) else: print(未知会员等级请重新输入)这段代码里外层先判断金额是否合法内层再分支会员等级钻石会员内部还有一个折扣上限的判断嵌套层级恰好控制在了三层以内。每个分支的输出都指向一个明确的结果要么输出实付金额要么输出错误提示。这就是前面所有知识点的综合应用。7.3 测试用例设计跑一遍边界值代码写完不算完测试才是重头戏。我设计了几条关键用例你可以把上面的代码跑一遍验证输入预期结果验证点0 黄金会员金额必须大于0非法输入拦截299 黄金会员未达到满减门槛实付299满减边界 299300 黄金会员满300减50实付250满减边界 3001000 钻石会员8折后减200上限实付800折扣上限生效100 钻石会员8折实付80折扣上限未触发100 超级会员未知会员等级非法等级兜底边界测试是写分支结构时最值的环节。你会发现很多 bug 不是逻辑写错了而是边界差一位。我在前文反复强调画数轴、用还是就是为了让测试时这些边界值能落在预期的区间。8. 我写判断逻辑时的几条“私房”经验最后分享几条我实际写代码养成的习惯不一定每条都对但确实帮我少踩了很多坑。第一先确定输出有几种结果再写判断。如果一段逻辑可能产生 4 种不同的提示那结构上大概率需要 4 个分支。从最终输出反推代码结构比对着业务描述一行行翻要高效得多。第二条件表达式的顺序永远按“最不可能命中”的放前面。这不是性能洁癖而是为了让异常情况尽早暴露。比如用户输入校验我会把非法输入放在最前面直接拦截掉后面的逻辑就不用关心脏数据了。第三能用字典映射解决的不写一长串 elif。比如一周的星期几、状态码对应的文案用字典更直观status_map { 1: 待支付, 2: 已支付, 3: 已发货, 4: 已完成, } print(status_map.get(current_status, 未知状态))这种写法本质上绕开了分支结构但它处理的是“纯映射”场景。如果映射背后还有条件判断那依然要回到 if 体系。第四写完分支结构后多问自己一句如果条件是0、空字符串、None程序会走到哪里这个习惯能帮你躲掉大量隐藏的异常。分支结构的内容到这里就说完了。回头你会发现在整个 Python 流程控制里if 类判断是使用频率最高的它不像循环那样需要凑齐条件也不像函数那样有额外的概念负担它只是帮程序在岔路口做出选择。把这些选择整理清楚后面的循环、函数、类写起来都会顺手很多。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑