08 - 条件判断程序不可能永远一条路走到黑很多时候需要根据不同的情况做不同的事。条件判断就是干这个的。if 语句最基本的条件判断age20ifage18:print(成年人了)如果条件为True就执行下面的代码块。注意条件后面有冒号:代码块必须缩进4 个空格这两条是 Python 的语法要求忘了任何一个都会报错。if-else两种情况选一age15ifage18:print(成年人)else:print(未成年)条件成立走if下面不成立走else下面。if-elif-else多种情况选一score85ifscore90:print(优秀)elifscore80:print(良好)elifscore60:print(及格)else:print(不及格)elif就是 “else if” 的缩写。可以有多个elifelse是兜底的可选。执行顺序是从上往下遇到第一个为 True 的条件就执行对应的代码块然后跳出整个 if-elif-else后面的条件不会再检查。所以上面score 85的时候虽然score 60也是 True但因为score 80先被匹配了所以输出良好。这意味着条件的顺序很重要。如果把score 60放第一个那 85 分也会输出及格这显然不对。嵌套 ifif 里面还可以套 ifage20has_ticketTrueifage18:ifhas_ticket:print(欢迎入场)else:print(请先买票)else:print(未成年不能入场)不过嵌套太多层代码会很丑也不好读。一般超过 3 层就该想想能不能简化了。一个常见的简化方式是用提前返回在函数里# 不太好defcheck_user(user):ifuserisnotNone:ifuser.is_active:ifuser.has_permission:return允许操作else:return没有权限else:return账号已停用else:return用户不存在# 更好提前返回/卫语句defcheck_user(user):ifuserisNone:return用户不存在ifnotuser.is_active:return账号已停用ifnotuser.has_permission:return没有权限return允许操作第二个版本没有嵌套从上往下读就行清爽多了。三元表达式如果 if-else 只是为了给一个变量赋值可以用三元表达式简写age20# 普通写法ifage18:status成年else:status未成年# 三元表达式status成年ifage18else未成年一行搞定。但别滥用条件复杂的时候老老实实写 if-else别为了炫技写那种一行几百字符的三元表达式。真值判断的简写Python 里很多东西可以直接放到 if 后面当条件用# 判断列表是否为空my_list[]ifmy_list:# 等价于 if len(my_list) 0print(有内容)ifnotmy_list:# 等价于 if len(my_list) 0print(空的)# 判断字符串是否为空nameifname:# 等价于 if name ! print(f你好{name})# 判断是否为 NoneresultNoneifresultisNone:# 判断 None 推荐用 isprint(没有结果)# 判断字典config{}ifconfig:# 等价于 if len(config) 0print(有配置)规律回顾0、、[]、{}、None、False在布尔上下文中都是False。match-casePython 3.10如果你用的是 Python 3.10 或更高版本可以用match-case语句类似其他语言的switch-casestatus200matchstatus:case200:print(OK)case404:print(Not Found)case500:print(Server Error)case_:print(Unknown)case _是通配符匹配所有情况相当于default。match-case 还能做模式匹配这是比 switch-case 强大的地方commandmove 10 20matchcommand.split():case[quit]:print(退出)case[move,x,y]:print(f移动到 ({x},{y}))case[attack,target]:print(f攻击{target})case_:print(未知命令)[move, x, y]会匹配三个元素的列表第一个是 “move”后两个自动绑定到变量 x 和 y。这个功能很强大但初期用 if-elif 也完全够用等你熟悉了再尝试。一个实际的例子写个小游戏把条件判断的用法串起来importrandom# 猜数字游戏secretrandom.randint(1,100)attempts0print(我想了一个 1 到 100 之间的数字猜猜看)whileTrue:guessinput(你的猜测)# 输入检查ifnotguess.isdigit():print(请输入一个数字)continueguessint(guess)attempts1ifguesssecret:print(太小了)elifguesssecret:print(太大了)else:print(f恭喜猜对了你一共猜了{attempts}次)break这段代码用了if-elif-else、while循环下一章详细讲、还有continue和break。你可能有些还没学到的东西但条件判断的部分应该能看懂了。本章小结if/elif/else做多条件分支条件匹配后跳出顺序很重要嵌套太多层就用提前返回卫语句来简化三元表达式值1 if 条件 else 值2空值判断可以直接用if x/if not x不用跟0、、[]比Python 3.10 的match-case可以做模式匹配面试题Q1Python 中if x和if x is not None有什么区别点击查看答案if x检查的是 x 的真值truthiness以下值都会被判断为 FalseNone0、0.0空字符串[]、{}、()、set()空容器Falseif x is not None只检查 x 是不是 None不检查其他值。所以当x 0或x 时if x→ False不执行if x is not None→ True执行选择取决于业务需求如果你需要区分没有值和值为0/空就要用is not None。Q2什么是卫语句Guard Clause为什么推荐点击查看答案卫语句是指在函数开头提前处理异常情况并返回避免深层嵌套。# 不用卫语句深层嵌套defprocess(user):ifuser:ifuser.is_active:# 真正要干的活...# 用卫语句扁平结构defprocess(user):ifnotuser:returnifnotuser.is_active:return# 真正要干的活...推荐原因减少嵌套层级代码更扁平易读主逻辑不需要缩进到很深的位置。也叫提前返回模式。Q3if-elif-else的执行顺序是怎样的如果有多个条件同时为 True 会怎样点击查看答案从上往下依次检查条件只执行第一个为 True 的分支然后跳出整个 if-elif-else 结构。即使后面的条件也为 True也不会执行。所以条件的排列顺序很重要——更具体、更严格的条件应该放在前面。score95ifscore60:print(及格)# 会执行这个虽然 90 也对elifscore90:print(优秀)# 不会执行应该把 90放在前面。Q4Python 的match-case跟 C/Java 的switch-case有什么区别点击查看答案主要区别模式匹配— Python 的 match 不仅匹配值还能匹配结构列表、元组、类实例等并自动提取变量不需要 break— C/Java 的 switch 需要手动 break 防止穿透Python 自动只匹配一个通配符— Python 用case _代替default更强大— 可以匹配类型、添加条件守卫guardcase x if x 0简单说 match-case 是 switch-case 的超级升级版。但注意需要 Python 3.10。上一章 | 下一章循环 →