你有没有过这种经历:
# 很多人的代码(包括三个月前的我)
def check_score(score):
if score >= 90:
grade = "A"
if score >= 80:
grade = "B"
if score >= 70:
grade = "C"
return grade
然后你发现自己永远只能得到A级,因为不管分数多少,都会被最后一个if覆盖...
更坑的是这样的循环:
# 让人脸黑的代码
students = ["小明", "小红", "小张"]
scores = [85, 92, 78]
for i in range(len(students)):
for j in range(len(scores)):
if students[i] == "小红":
print(f"{students[i]}的分数是{scores[i]}")
break # 这个break只跳出内层循环
最后你发现小红只打印了一次,但小明和小张的信息完全丢了...
今天咱们就来彻底搞懂Python的条件语句和循环,让你从此写出让人眼前一亮的代码。
条件语句:不只是if和else那么简单
从C语言思维到Python思维
很多人写Python还带着C语言的阴影:
# C语言风格的Python代码(丑爆了)
if condition == True:
do_something()
if condition == False:
do_other()
if len(list) > 0:
process_list()
Pythonic的写法:
# 优雅的Python风格
if condition:
do_something()
else:
do_other()
if my_list: # 空列表自动为False
process_list()
记住:Python的if后面跟的是"真值表达式",不是布尔表达式。
什么是真值?简单说:
0,"",[],{},None,False→ 假值- 其他一切 → 真值
elif的威力
很多人的条件判断像这样:
# 嵌套地狱
if age < 18:
print("未成年")
else:
if age < 30:
print("年轻人")
else:
if age < 50:
print("中年人")
else:
print("老年人")
这就是我说的"金字塔代码",看得人想吐...
正确的姿势:
# 扁平结构,一目了然
if age < 18:
print("未成年")
elif age < 30:
print("年轻人")
elif age < 50:
print("中年人")
else:
print("老年人")
elif比嵌套if更优雅,性能也更好。因为一旦某个条件满足,就不会继续检查后面的条件。
三元运算符:一行代码的优雅
传统写法:
if score >= 60:
result = "及格"
else:
result = "不及格"
Pythonic写法:
result = "及格" if score >= 60 else "不及格"
但别滥用!复杂的判断还是老老实实写if:
# 这样的三元运算符就是灾难
result = "优秀" if score >= 90 else "良好" if score >= 80 else "及格" if score >= 60 else "不及格"
# 不如写成清晰的多行if
if score >= 90:
result = "优秀"
elif score >= 80:
result = "良好"
elif score >= 60:
result = "及格"
else:
result = "不及格"
循环:让你的代码跑起来
for循环:不是只能range()
很多初学者只知道:
# 最基础的用法
for i in range(10):
print(i)
但Python的for循环远不止于此:
# 直接遍历列表
fruits = ["苹果", "香蕉", "橙子"]
for fruit in fruits:
print(f"我喜欢吃{fruit}")
# 同时获取索引和值
for index, fruit in enumerate(fruits):
print(f"第{index}个水果是{fruit}")
# 遍历字典
person = {"name": "张三", "age": 25, "city": "北京"}
for key, value in person.items():
print(f"{key}: {value}")
# 反向遍历
for fruit in reversed(fruits):
print(f"倒序:{fruit}")
while循环:别把自己玩死
新手最容易犯的错误:
# 致命的死循环
count = 0
while count < 10:
print(count)
# 忘记count += 1,CPU:我太难了!
正确的写法:
count = 0
while count < 10:
print(count)
count += 1 # 记得更新循环条件!
while循环适合不知道具体次数的情况:
# 等待用户输入正确答案
while True:
answer = input("Python的创始人是谁?")
if answer.lower() == "guido van rossum":
print("答对了!")
break
else:
print("再想想...")
break和continue:控制的艺术
break:说走就走
# 找到第一个满足条件的就停止
numbers = [1, 3, 5, 7, 9, 2, 4, 6]
for num in numbers:
if num % 2 == 0:
print(f"找到第一个偶数:{num}")
break
# 输出:找到第一个偶数:2
continue:跳过这一次
# 只要偶数,跳过奇数
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
for num in numbers:
if num % 2 != 0:
continue # 跳过奇数
print(f"偶数:{num}")
# 输出:偶数:2 4 6 8
else子句:循环的彩蛋
99%的Python程序员都不知道循环还有else子句!
# 寻找素数
for num in range(2, 10):
for i in range(2, num):
if num % i == 0:
print(f"{num}不是素数")
break
else:
# 只有循环正常结束(没有break)才会执行
print(f"{num}是素数")
else什么时候执行?
- for循环:遍历完所有元素后执行
- while循环:条件变为False时执行
- 如果遇到break,else不会执行
这比使用标志变量优雅多了:
# 传统写法(繁琐)
is_prime = True
for i in range(2, num):
if num % i == 0:
is_prime = False
break
if is_prime:
print(f"{num}是素数")
# Pythonic写法(简洁)
for i in range(2, num):
if num % i == 0:
print(f"{num}不是素数")
break
else:
print(f"{num}是素数")
实战场景:让知识落地
场景1:用户权限判断
# 复杂的权限系统
def check_permission(user):
if not user or not user.get("is_active"):
return "无权限:用户不存在或已禁用"
if user.get("role") == "admin":
return "超级管理员权限"
elif user.get("role") == "editor":
if user.get("department") == "tech":
return "技术编辑权限"
else:
return "普通编辑权限"
elif user.get("level", 0) >= 5:
return "高级用户权限"
else:
return "基础用户权限"
场景2:数据处理流水线
# 处理用户数据
def process_users(users):
results = []
for user in users:
# 跳过无效用户
if not user or not user.get("email"):
continue
# 数据清洗
cleaned_user = {
"name": user.get("name", "未知用户").strip(),
"email": user["email"].lower(),
"level": user.get("level", 1)
}
# 权限判断
if cleaned_user["level"] >= 5:
cleaned_user["permission"] = "高级"
elif cleaned_user["level"] >= 3:
cleaned_user["permission"] = "中级"
else:
cleaned_user["permission"] = "基础"
results.append(cleaned_user)
return results
# 使用示例
users = [
{"name": "张三", "email": "zhangsan@example.com", "level": 6},
{"name": " 李四 ", "email": "LISI@EXAMPLE.COM", "level": 2},
{"name": "", "email": "", "level": 1}, # 会被跳过
{"name": "王五", "email": "wangwu@example.com"} # 默认level=1
]
processed = process_users(users)
for user in processed:
print(f"{user['name']} - {user['email']} - {user['permission']}")
场景3:游戏逻辑
# 简单的猜数字游戏
import random
def guess_number_game():
target = random.randint(1, 100)
attempts = 0
max_attempts = 7
print("我想了一个1-100之间的数字,你有7次机会猜!")
while attempts < max_attempts:
try:
guess = int(input(f"第{attempts + 1}次猜测:"))
attempts += 1
if guess == target:
print(f"🎉 恭喜!你用{attempts}次就猜中了!")
break
elif guess < target:
print("太小了!")
else:
print("太大了!")
# 剩余次数提示
remaining = max_attempts - attempts
if remaining > 0:
print(f"还剩{remaining}次机会")
except ValueError:
print("请输入数字!")
attempts -= 1 # 不计入有效尝试
else:
# while循环正常结束(用户没猜中)
print(f"😅 很遗憾,正确答案是{target}")
# 运行游戏
# guess_number_game()
常见坑爹错误及解决方案
坑1:缩进错误
Python的灵魂是缩进,一个Tab键毁所有:
# 错误示例:缩进不一致
if condition:
print("条件成立")
print("这是错误的缩进")
# 正确示例:统一使用4个空格
if condition:
print("条件成立")
print("正确的缩进")
建议: 配置编辑器自动将Tab转换为4个空格。
坑2:修改正在遍历的列表
# 致命错误:修改正在遍历的列表
numbers = [1, 2, 3, 4, 5]
for num in numbers:
if num % 2 == 0:
numbers.remove(num) # 这会搞乱迭代器
print(numbers) # 结果可能是 [1, 3, 5] 或 [1, 2, 3, 5]
# 正确做法:创建新列表或遍历副本
numbers = [1, 2, 3, 4, 5]
odd_numbers = []
for num in numbers:
if num % 2 != 0:
odd_numbers.append(num)
print(odd_numbers) # [1, 3, 5]
# 或者用列表推导式(更Pythonic)
odd_numbers = [num for num in numbers if num % 2 != 0]
坑3:循环变量的作用域
# Python 2.x的坑(在Python 3中已修复)
for i in range(5):
pass
print(i) # Python 2中会输出4,Python 3中会报错
# 建议总是显式初始化
i = None
for i in range(5):
pass
print(i) # 安全的做法
坑4:忘记else的坑爹逻辑
# 常见错误:以为if-else的else对应for
for item in items:
if condition(item):
process(item)
break
else:
# 这个else不是if的else,是for的else!
print("没有找到符合条件的item")
记住:循环的else子句在循环正常结束时执行,不是if的else!
性能优化技巧
技巧1:使用生成器表达式
# 列表推导式(立即创建列表)
squares = [x**2 for x in range(1000000)] # 占用内存
# 生成器表达式(按需生成)
squares_gen = (x**2 for x in range(1000000)) # 节省内存
# 处理大数据时优先考虑生成器
total = sum(x**2 for x in range(1000000)) # 直接计算,不存储中间结果
技巧2:避免不必要的循环
# 低效做法
result = []
for item in items:
if item in valid_items:
result.append(process(item))
# 高效做法
valid_set = set(valid_items) # 转换为set,查找O(1)
result = [process(item) for item in items if item in valid_set]
技巧3:使用内置函数
# 自己实现的循环
total = 0
for num in numbers:
total += num
# 使用内置函数
total = sum(numbers)
# 多个条件
# 写法1:多个if
if age >= 18:
if has_license:
if not_drunk:
print("可以开车")
# 写法2:and连接
if age >= 18 and has_license and not_drunk:
print("可以开车")
# 写法3:all函数(最优雅)
conditions = [age >= 18, has_license, not_drunk]
if all(conditions):
print("可以开车")
调试技巧:让bug无处可藏
技巧1:print大法
# 调试循环
for i, item in enumerate(items):
print(f"Debug: i={i}, item={item}, condition={condition(item)}")
if condition(item):
process(item)
技巧2:使用断言
def calculate_price(quantity, unit_price):
assert quantity >= 0, "数量不能为负数"
assert unit_price >= 0, "单价不能为负数"
total = quantity * unit_price
assert total >= 0, "总价计算错误"
return total
技巧3:分步调试复杂条件
# 复杂条件难以调试
if user and user.is_active and user.level >= 3 and (user.role == "admin" or user.has_permission):
# 分步写法便于调试
if not user:
print("用户不存在")
elif not user.is_active:
print("用户未激活")
elif user.level < 3:
print("用户等级不够")
elif user.role == "admin":
print("管理员权限")
elif user.has_permission:
print("特殊权限")
else:
print("无权限")
总结
记住一句话:代码是写给人看的,顺便给机器执行。
- 条件语句:保持扁平结构,避免嵌套地狱
- 循环:善用for遍历,谨慎使用while
- 控制流:break用于提前退出,continue用于跳过
- else子句:循环的彩蛋,在循环正常结束时执行
- 可读性:比炫技更重要,你的同事会感谢你
下次再写条件语句和循环时,想想今天的这篇文章。你的代码不仅会运行正确,还会让人赏心悦目。
你在项目里遇到过什么坑爹的条件或循环问题?评论区聊聊,看看谁的bug更奇葩!