Python3 条件控制新手实战指南
WEB项目地址:演示地址
先聊两句
条件判断这东西,说白了就是让程序学会"看人下菜碟"。你输入用户名密码,它判断对不对,对了放行错了拦下------这就是最典型的条件控制。
我刚开始学的时候老觉得if太简单了,有啥好讲的。结果写了个用户注册的逻辑,七八个if套在一起,改了一个地方崩了三个功能。后来才明白,条件判断不在难,在怎么写得清楚、改得动。
这篇文章就盯着新手容易懵的点聊。你跟着敲一遍,至少不会再被缩进报错折磨半小时。
一、布尔值与比较运算符快速入门
条件判断绕不开布尔值------True和False,首字母必须大写,这个记死了。
python
# 哪些东西自带布尔值?先记住这几个
print(bool(0)) # False
print(bool(1)) # True
print(bool("")) # False
print(bool("abc")) # True
print(bool([])) # False
print(bool([1, 2])) # True
print(bool(None)) # False
空的东西大多是False,非空的基本是True。这条规则记住,后面讲真假值判定的时候会用上。
比较运算符返回的就是布尔值:
python
age = 20
print(age >= 18) # True
print(age == 18) # False
print(age != 18) # True
Python支持连写比较,这个写起来很舒服:
python
score = 85
if 80 <= score < 90:
print("良好") # 这下会打印
其他语言得写成score >= 80 && score < 90,Python不用。
新手容易搞混的地方 :=是赋值,==是判等。写if age = 18直接报语法错误,因为赋值语句不能出现在条件位置。我见过有人因为这个卡了二十分钟。
二、if语句基础结构与缩进规范
先看一个完整的if结构长啥样:
python
age = int(input("输入年龄: "))
if age >= 18:
print("你已经成年了")
print("可以去考驾照了")
重点说缩进。
Python用缩进来表示代码块,不像C/Java用大括号。同一层级的代码缩进必须一致。
python
# 这样写会报错
if age >= 18:
print("成年了")
print("这行缩进不对") # IndentationError
缩进用几个空格? PEP8推荐4个。但更重要的是保持统一,不要这段用4个空格那段用Tab。大多数编辑器可以设置"Tab转空格",打开这个功能省很多事。
这里有个很多人不知道的:缩进不光是空格数一致,空格和Tab混用会直接报错,肉眼看不出来那种。VSCode右下角能看到当前文件用的是空格还是Tab,如果混了会显示"混合缩进"。
python
# 看起来一样,但一个用了空格一个用了Tab
if True:
print("这行用了4个空格")
print("这行用了Tab") # 肉眼看不出来,但运行报错
三、elif多分支逻辑判断实战
elif是else if的缩写,用来处理多个互斥的条件:
python
score = 78
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}") # C
注意elif的条件判断顺序是从上到下 ,一旦匹配就停止往下走了。score=78匹配到>=70这个分支,后面的>=60不会再判断。
很多新手会写出这样的代码:
python
# 画蛇添足
if score >= 90:
grade = "A"
if score >= 80 and score < 90: # 其实不需要 and score < 90
grade = "B"
if score >= 70 and score < 80:
grade = "C"
用elif就干净多了,而且每个条件只判断一次。上面那种写法不仅啰嗦,而且score=95的时候第一和第二个if都会执行(虽然不影响结果,但浪费性能)。
四、else默认处理机制应用
else是"以上条件都不满足"时的兜底方案。很多逻辑里它充当默认值的角色:
python
# 用户输入用户名,没输入就给个默认名
username = input("请输入用户名: ")
if username.strip() == "":
username = "游客"
else:
print(f"欢迎回来, {username}")
还有错误处理的场景:
python
import re
phone = input("输入手机号: ")
if re.match(r'^1[3-9]\d{9}$', phone):
print("手机号格式正确")
else:
print("手机号格式有误,请重新输入")
else还有个容易被忽视的用法------和循环配合。for和while可以带else,循环正常走完(没有被break打断)就会执行else块:
python
# 查找列表中是否有某个元素
items = [1, 2, 3, 4, 5]
target = 6
for item in items:
if item == target:
print("找到了!")
break
else:
print("没找到") # 循环没有被break,执行这里
这个写法比设一个found标志变量清爽很多。不过新手看这个容易懵,先知道有这么回事就行。
五、嵌套条件判断场景解析
嵌套就是if里面再套if。能避免就避免,但有些场景确实绕不开。
一个常见的嵌套场景------先判断大条件,再细化判断:
python
age = 25
has_license = True
if age >= 18:
if has_license:
print("可以租车")
else:
print("需要先考驾照")
else:
print("未成年不能租车")
这种可以优化成and连接:
python
if age >= 18 and has_license:
print("可以租车")
elif age >= 18 and not has_license:
print("需要先考驾照")
else:
print("未成年不能租车")
但嵌套太深了谁也救不了:
python
# 三层嵌套,看五分钟不知道在干嘛
if condition1:
if condition2:
if condition3:
do_something()
else:
do_other()
else:
do_third()
else:
do_fourth()
碰到这种代码,要么提前返回 (如果是在函数里),要么拆成多个独立的if ,要么重新设计逻辑。三层以上的嵌套基本意味着思路该理一理了。
六、and/or/not逻辑组合技巧
and:全真才真。or:一真就真。not:取反。
这部分真正的难点在于短路求值。
python
# and 短路:左边为False,右边根本不会执行
def expensive_check():
print("这个函数执行了")
return True
if False and expensive_check():
print("不会打印")
# "这个函数执行了" 不会打印,因为左边的False已经让整个and确定为False了
# or 短路:左边为True,右边不执行
if True or expensive_check():
print("会打印")
# "这个函数执行了" 不会打印
这个特性在写防御性代码的时候特别有用:
python
# 安全地获取嵌套字典的值
user = {"profile": {"name": "张三"}}
if user and user.get("profile") and user["profile"].get("name"):
print(user["profile"]["name"])
# 用短路特性简化
name = user and user.get("profile") and user["profile"].get("name")
# 如果中间某个不存在,name就是False(或None),不会报错
再比如给默认值:
python
# 如果用户没输入名字,用默认值
name = input("输入名字: ") or "匿名用户"
print(name)
or的短路特性让这行代码既安全又简洁。但别滥用,太长的or链读起来很费劲。
七、三元表达式简洁写法演示
三元表达式就是把if-else压缩成一行,语法是结果1 if 条件 else 结果2:
python
age = 20
status = "成年" if age >= 18 else "未成年"
print(status) # 成年
这个比写四行if-else省地方,适合简单的二选一赋值:
python
# 取最大值
a, b = 10, 20
max_val = a if a > b else b
# 格式化输出
price = 99.9
tip = "需要配送费" if price < 100 else "免配送费"
但别把三元表达式搞复杂了:
python
# 让人看不懂的写法
result = a if a > b else b if b > c else c # 虽然能跑
# 换成if-elif-else,三秒钟就看懂了
if a > b and a > c:
result = a
elif b > c:
result = b
else:
result = c
嵌套三元表达式基本等于给后面维护的人埋雷。我个人的标准是:写在一行里超过80个字符,就老老实实换回if-else。
八、真假值判定规则详解
Python里每个对象都可以当布尔值用,不光是True和False。
会被判定为False的值(记住这几种就够了):
NoneFalse- 数值0(
0,0.0,0j) - 空序列/集合(
"",[],(),{},set(),range(0))
其他所有值都是True。
这个规则的妙处是你可以直接写:
python
# 不用写成 if len(name) > 0
name = "张三"
if name:
print(f"你好, {name}")
else:
print("名字不能为空")
# 不用写成 if len(items) != 0
items = [1, 2, 3]
if items:
print(f"有{len(items)}个项目")
# 不用写成 if user is not None and user != {}
user = {"name": "张三"}
if user:
print(user["name"])
很多新手会这样写:
python
if name == True: # 多此一举
if items != []: # 虽然能跑但不Pythonic
if len(name) > 0: # 可以但啰嗦
记住:if x 比 if x == True 更地道,也比 if x is True 更宽松(因为后者要求x必须是布尔True,而if x能接受任何真值)。
九、常见缩进错误与排查方法
条件控制相关的报错,80%是缩进问题。遇到这类错误不用慌,挨个排查。
错误1:IndentationError: expected an indented block
意思是"这里应该有缩进"。if、elif、else、for、while、def后面的代码块必须有缩进。
python
# 错误
if age > 18:
print("成年了") # 缩进没对齐
# 如果暂时不想写逻辑,用pass占位
if age > 18:
pass # pass就是啥也不做,占位用的
错误2:IndentationError: unindent does not match any outer indentation level
缩进级别不一致。检查前后缩进的空格数是否相同。
错误3:Tab和空格混用
编辑器里看不出来,但运行报错。排查方法:
- VSCode:右下角点击"空格"或"Tab"可以切换,也能看到当前文件用的是什么
- 用
python -t运行脚本会警告Tab和空格混用 - 编辑器设置"显示空白字符",就能看到所有的点和箭头
实践建议:
- 编辑器设置"Tab键转换为空格",并且用4个空格
- 写代码的时候盯着缩进对齐线看
- 如果报缩进错误,把这段代码的缩进全部删了重新打一遍
十、用户输入验证综合案例
把上面的东西串起来,写一个用户注册信息验证的小程序。
python
import re
def validate_username(username):
"""用户名:3-12位,字母数字下划线"""
if not username:
return False, "用户名不能为空"
if len(username) < 3 or len(username) > 12:
return False, "用户名长度需为3-12位"
if not re.match(r'^[a-zA-Z0-9_]+$', username):
return False, "用户名只能包含字母、数字、下划线"
return True, "用户名可用"
def validate_password(password, confirm):
"""密码:至少8位,包含字母和数字"""
if not password:
return False, "密码不能为空"
if len(password) < 8:
return False, "密码至少8位"
if not re.search(r'[a-zA-Z]', password):
return False, "密码需要包含字母"
if not re.search(r'\d', password):
return False, "密码需要包含数字"
if password != confirm:
return False, "两次输入的密码不一致"
return True, "密码可用"
def validate_email(email):
"""邮箱:简单格式验证"""
if not email:
return False, "邮箱不能为空"
if not re.match(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$', email):
return False, "邮箱格式不正确"
return True, "邮箱格式正确"
def main():
print("=" * 40)
print("用户注册信息验证")
print("=" * 40)
# 收集用户输入
username = input("用户名: ").strip()
password = input("密码: ").strip()
confirm = input("确认密码: ").strip()
email = input("邮箱: ").strip()
# 逐项验证,只要有一项失败就停止
valid, msg = validate_username(username)
if not valid:
print(f"❌ {msg}")
return
valid, msg = validate_password(password, confirm)
if not valid:
print(f"❌ {msg}")
return
valid, msg = validate_email(email)
if not valid:
print(f"❌ {msg}")
return
# 所有验证通过
print("✅ 所有信息验证通过!")
print(f"用户名: {username}")
print(f"邮箱: {email}")
print("密码: ********")
if __name__ == "__main__":
main()
运行效果:
markdown
========================================
用户注册信息验证
========================================
用户名: 张三
❌ 用户名只能包含字母、数字、下划线
makefile
用户名: zhangsan
密码: 123456
确认密码: 123456
邮箱: zhangsan@qq.com
❌ 密码需要包含字母
makefile
用户名: zhangsan
密码: abc12345
确认密码: abc12345
邮箱: zhangsan@qq.com
✅ 所有信息验证通过!
用户名: zhangsan
邮箱: zhangsan@qq.com
密码: ********
这个例子把if、elif、else、and/or/not、真假值判定、比较运算符都串起来了。你可以试着改改验证规则,比如用户名不能用纯数字、密码不能包含用户名之类的,练练手。
最后说两句
条件控制说到底是"让程序做选择题"。代码怎么写才算好?我自己的标准是:别人(包括三个月后的自己)看一遍就能明白这段逻辑在干嘛。
缩进统一用4个空格,嵌套不超过三层,复杂的and/or链拆成带名字的变量------这些小习惯比学会某个高级技巧重要得多。
前面讲的验证案例你可以跑一遍,改改规则、换换输入,看看输出变化。遇到报错就看看是哪类缩进错误,多折腾几次就有数了。
如果卡在某个点上,把这个条件拆成最简的形式,一行一行打印中间结果,慢慢就定位到问题了。写代码这事儿,调试的时间永远比写的时间长,习惯就好。