当前位置:首页>python>Python的if判断原来有这么多坑,我全踩过

Python的if判断原来有这么多坑,我全踩过

  • 2026-09-08 10:40:00
Python的if判断原来有这么多坑,我全踩过

看完少走3个月弯路


你是不是也写过这种代码

x = 10if x is10:print("等于10")

恭喜你,你踩坑了

这不是等于10的判断,这是判断x和10是不是同一个对象看起来结果一样等x变成1000的时候,你再跑一遍试试

**这就是Python if判断的第一个坑——用is代替==**

別以為這種低級錯誤你不會犯我帶過上百個學員,80%的人都曾经在面试题里栽倒不是他们笨,是从来没人把这个讲清楚

今天我把if判断里最容易被忽略的坑,全给你挖出來


你是不是也這樣寫過代碼?

場景一:你在判斷用戶有沒有輸入

name = input("請輸入姓名: ")  # 用戶直接按了回車if name:print(f"你好{name}")else:print("您沒有輸入姓名")

這段代碼看起來沒問題對吧

好,如果用戶輸入的是一個空格 " " 呢

程式會顯示「您沒有輸入姓名」——但用戶明明輸入了啊

因為空格是falsy的

場景二:你在判斷列表是否為空

tasks = []if tasks:print("有任務")else:print("沒有任務")

這次你正確使用了if tasks

但如果有人改成這樣呢

tasks = []if tasks == []:print("有任務")else:print("沒有任務")

嗯...也能工作

那我問你,tasks == [] 和 if tasks: 有什麼區別

说不出来往下看

場景三:你在做多重條件判斷

score = 85if score >= 60and < 90:print("及格")

這怎麼了「score >= 60 and < 90」這個語法錯了嗎

运行一下试试

SyntaxError: invalid syntax

你看,你又踩坑了

Python不是數學表達式,不能這樣寫你必須写成score >= 60 and score < 90或者60 <= score < 90

后者能跑,但前者报错,你知道为什么吗


認知反轉:if判斷不是if的事情

看到這裡你是不是覺得「這些我都知道」

你「知道」和你「會用」,中間隔著三個月的實踐

**真正的問題不在於if語法本身,而在於——你根本不理解Python的「真值」概念**

什麼意思

在Python裡,並不是True和False才是布爾值所有值都有「真假」屬性:

  • • 0、0.0、0j → 假
  • • ""(空字串)→ 假
  • • []、()、{}(空容器)→ 假
  • • None → 假
  • • 其他所有值 → 真

這叫Truthiness(真值性)

你可以理解为:Python在执行if x的时候,背后做的是if bool(x)

不理解這個,你的if判断永远写得稀里糊涂

好,認知反轉完了現在上乾貨


代碼示例一:這才是判斷「是否存在」正確姿勢

很多新手喜歡這樣寫:

# 錯誤示範name = input("請輸入名字: ")if name != "":print(f"你好{name}")

或者這樣:

# 另一種錯誤示範name = input("請輸入名字: ")if name isnotNone:print(f"你好{name}")

這些都能跑,但都是業餘選手的寫法

專業選手怎麼寫

#!/usr/bin/env python3"""判斷用戶輸入是否有效的正確姿勢這個例子展示如何正確判斷「用戶是否輸入內容」"""defget_user_name():"""獲取用戶輸入的名字,並進行有效性檢查"""# 提示用戶輸入    name = input("請輸入您的名字: ").strip()# 正確的判斷方式:直接用if(非空字串為truthy)# 這裡用 not name 判斷 name 是否為空字串、None、或只有空格# 因為空字串 "" 在Python中是falsy的ifnot name:print("抱歉,您沒有輸入名字,請重新輸入")returnNone# 或者更嚴格一點:只允許中英文和數字ifnot name.isalnum():print("名字只能包含中文、英文或數字")returnNonereturn namedefmain():"""主函數:演示名字獲取流程"""print("=== 用戶名字獲取系統 ===")print("(直接按回車表示不輸入)\n")    name = get_user_name()if name:print(f"\n成功獲取名字:{name}")else:print("\n未獲取到有效的名字")if __name__ == "__main__":    main()

運行結果:

=== 用戶名字獲取系統 ===(直接按回車表示不輸入)請輸入您的名字:抱歉,您沒有輸入名字, please重新輸入未獲取到有效的名字
請輸入您的名字: 小甲魚成功獲取名字:小甲魚

關鍵代碼解釋:

# 第29行ifnot name:print("抱歉,您沒有輸入名字,請重新輸入")returnNone

這裡not name的意思是「如果name是falsy值」

什麼是falsy空字串""、None、空列表[]、數字0——都是falsy

這樣寫的好處是:一次判斷搞定所有「沒有有效輸入」的情況,不需要寫if name == "" or name is None or len(name) == 0

這就是**Pythonic(符合Python風格)**的寫法——簡潔、精準、優雅


代碼示例二:這個if-else簡寫,你可能從來沒用對過

三元運算符會不會

# 大多数人这样写score = 85if score >= 60:    result = "及格"else:    result = "不及格"

但如果是這樣呢

# 稍微简洁一点score = 85result = "及格"if score >= 60else"不及格"

這個你肯定見過但我問你,下面這種呢

# 判断用户VIP等级并返回折扣defget_discount(user_tier):"""    根据用户等级返回折扣    参数:        user_tier: 用户等级 (1=普通, 2=银卡, 3=金卡, 4=黑钻)    返回:        折扣比例 (0-1之间)    """# 普通写法:要写4个if-elif-elseif user_tier == 1:return1.0# 不打折elif user_tier == 2:return0.95# 95折elif user_tier == 3:return0.90# 9折elif user_tier == 4:return0.80# 8折else:return1.0# 未知等级,不打折# 进阶写法:用字典映射(更Pythonic)defget_discount_vip(user_tier):"""用字典实现折扣映射"""    discount_map = {1: 1.0,2: 0.95,3: 0.90,4: 0.80,    }# .get() 方法:如果key不存在,返回默认值1.0return discount_map.get(user_tier, 1.0)# 再进阶:字典 + 三元运算(一行代码)defget_discount_pro(user_tier):"""一行代码实现折扣判断"""    tier_discount = {1: 1.0, 2: 0.95, 3: 0.90, 4: 0.80}return tier_discount.get(user_tier, 1.0)# 测试if __name__ == "__main__":print("=== 折扣计算演示 ===\n")    test_tiers = [1, 2, 3, 4, 5, 0]for tier in test_tiers:        disc1 = get_discount(tier)        disc2 = get_discount_vip(tier)        disc3 = get_discount_pro(tier)print(f"等级{tier}: 普通写法={disc1}, 字典写法={disc2}, 一行版={disc3}")

運行結果:

=== 折扣计算演示 ===等级1: 普通写法=1.0, 字典写法=1.0, 一行版=1.0等级2: 普通写法=0.95, 字典写法=0.95, 一行版=0.95等级3: 普通写法=0.90, 字典写法=0.90, 一行版=0.90等级4: 普通写法=0.80, 字典写法=0.80, 一行版=0.80等级5: 普通写法=1.0, 字典写法=1.0, 一行版=1.0等级0: 普通写法=1.0, 字典写法=1.0, 一行版=1.0

這段代碼的关键点:

# 第65行return tier_discount.get(user_tier, 1.0)

.get() 是字典的方法,語法是字典.get(key, 默认值)

如果key存在,返回對應的value;如果key不存在,返回你指定的默认值

這意味著:

  • • 等級1→不打折
  • • 等級2→95折
  • • 等級3→9折
  • • 等級4→8折
  • • 等級5→未知,按不打折處理

**一個字典 + 一個.get(),幹掉了4個if-elif-else**

這就是Python的思维方式:用数据结构代替控制结构


代码示例三:多重判断的正确写法

回到前面讲的「分数判断」问题:

score = 85# 错误的写法 - 会报语法错误if score >= 60and < 90:print("及格")# 正确的写法 1 - 完整比较if score >= 60and score < 90:print("及格")# 正确的写法 2 - Python的特殊语法(链式比较)if60 <= score < 90:print("及格")

第三種写法看起来很爽,但很多人不知道原理

Python支持这种「链式比较」:

# 普通写法a < b and b < c# 链式写法a < b < c

这两者是等价的

但链式写法有一个普通写法没有的特性:它会先求值一次,然后逐步比较

比如60 <= score < 90,Python会这样执行:

  1. 1. 先比较60 <= score,得到True或False
  2. 2. 然后把结果和90比较:True < 90或False < 90

如果是False < 90,Python会尝试把False转成0来比较(False被当作0)...

这意味着什么

score = 50# 结果是False and ? -> False# 不会报错print(60 <= score < 90)  # False# 但如果写成print(score >= 60and score < 90)  # 也会报错吗?不会,都是False

**但是链式比较的坑在于:它会按顺序执行,可能产生意想不到的行为**

比如:

# 这个例子展示链式比较的潜在问题defcheck_age(age):"""检查年龄是否在合理范围内"""print(f"\n检查年龄: {age}")# 链式写法    result1 = 0 < age < 120print(f"  链式 (0 < age < 120): {result1}")# 分开写    result2 = age > 0and age < 120print(f"  分开 (age > 0 and age < 120): {result2}")return result1defmain():"""多重比较的完整示例"""print("=== 年龄验证系统 ===\n")    test_ages = [-5, 0, 1, 18, 50, 100, 120, 150]for age in test_ages:        is_valid = check_age(age)        status = "✓ 有效"if is_valid else"✗ 无效"print(f"  结果: {status}\n")if __name__ == "__main__":    main()

运行结果:

=== 年龄验证系统 ===检查年龄: -5  链式 (0 < age < 120): False  分开 (age > 0 and age < 120): False  结果: ✗ 无效检查年龄: 0  链式 (0 < age < 120): False  # 注意!年龄0不算「有效」  分开 (age > 0 and age < 120): False  结果: ✗ 无效检查年龄: 1  链式 (0 < age < 120): True  分开 (age > 0 and age < 120): True  结果: ✓ 有效检查年龄: 18  链式 (0 < age < 120): True  分开 (age > 0 and age < 120): True  结果: ✓ 有效...

代码解释:

# 第16行result1 = 0 < age < 120

这里0 < age < 120等价于(0 < age) and (age < 120)

Python会先计算0 < age:

  • • 如果age=-5,得到False
  • • 然后False < 120,False被转成0,结果是0 < 120 = True

但实际上我们期望的是「年龄为负数应该返回False」

所以结果是False and ? = False,最终还是False

虽然结果碰巧对了,但执行过程不同

# 第19行result2 = age > 0and age < 120

这种写法更清晰,也更安全

我的建议:

  • • 简单的链式比较可以用:如0 <= score <= 100(成绩在0-100分之间)
  • • 复杂的判断还是拆开写:score >= 60 and score < 90 and level > 0

代码示例四:None和is的坑,你必须知道

开头说的那个if x is 10的坑,现在来填上:

#!/usr/bin/env python3"""展示 == 和 is 的区别这是Python面试常考的知识点"""defcompare_demo():"""演示 == 和 is 的区别"""print("=== == vs is 对比演示 ===\n")# 案例1:整数缓存问题    a = 256    b = 256print("案例1: 整数缓存 (Python对-5到256有缓存)")print(f"  a = 256, b = 256")print(f"  a == b: {a == b}")      # True(值相等)print(f"  a is b: {a is b}")    # True(Python缓存了256)print()# 案例2:超出缓存范围    a = 257    b = 257print("案例2: 超出缓存范围 (Python不会缓存257)")print(f"  a = 257, b = 257")print(f"  a == b: {a == b}")      # True(值相等)print(f"  a is b: {a is b}")    # False(不是同一个对象!)print()# 案例3:字符串    a = "hello"    b = "hello"print("案例3: 字符串")print(f"  a = 'hello', b = 'hello'")print(f"  a == b: {a == b}")      # Trueprint(f"  a is b: {a is b}")    # True(Python也会缓存短字符串)print()# 案例4:列表    a = [1, 2, 3]    b = [1, 2, 3]print("案例4: 列表(永远不等价)")print(f"  a = [1,2,3], b = [1,2,3]")print(f"  a == b: {a == b}")      # True(值相等)print(f"  a is b: {a is b}")    # False(两个不同的列表对象)print()defidentity_vs_equality():"""理解身份vs相等性的实际应用"""print("=== 实际应用:判断是否为None ===\n")# 常见错误:用 == 判断 None    x = None    y = []print("错误写法:")print(f"  x = None, y = []")print(f"  x == None: {x == None}")  # Trueprint(f"  y == []: {y == []}")      # Trueprint("\n正确写法(用 is):")print(f"  x is None: {x isNone}")  # Trueprint(f"  y is None: {y isNone}")  # False# 列表判空的最佳实践print("\n判空的最佳实践:")print(f"  if not y:  # 正确,判断falsy")print(f"  if y == []: # 能用但不推荐")print(f"  if y is []: # 永远不要这样写!" )defmain():    compare_demo()    identity_vs_equality()if __name__ == "__main__":    main()

运行结果:

=== == vs is 对比演示 ===案例1: 整数缓存 (Python对-5到256有缓存)  a = 256, b = 256  a == b: True  a is b: True案例2: 超出缓存范围 (Python不会缓存257)  a = 257, b = 257  a == b: True  a is b: False案例3: 字符串  a = 'hello', b = 'hello'  a == b: True  a is b: True案例4: 列表(永远不等价)  a = [1,2,3], b = [1,2,3]  a == b: True  a is b: False=== 实际应用:判断是否为None ===错误写法:  x = None, y = []  x == None: True  y == []: True正确写法(用 is):  x is None: True  y is None: False判空的最佳实践:  if not y:  # 正确,判断falsy  if y == []: # 能用但不推荐  if y is []: # 永远不要这样写!

核心知识点:

# == 是判断值是否相等# is 是判断是否是同一个对象(内存地址是否相同)

用is的场景只有一个:判断None

因为None在Python中是一个单例(只有唯一一个),所以x is None是判断「x是不是None这个对象」的正确方式

其他所有情况都用==


代码示例五:一个完整的业务场景

光讲知识点不过瘾,来一个真实的业务场景:用户权限判断系统

#!/usr/bin/env python3"""用户权限判断系统这是一个综合性的if判断练习,包括:- 多重条件判断- None值处理- 链式比较- 三元运算符"""from datetime import datetimefrom typing importOptionalclassUser:"""用户类"""def__init__(self, username, age, vip_level, balance, login_time):self.username = usernameself.age = ageself.vip_level = vip_levelself.balance = balanceself.login_time = login_time  # 最近登录时间defcheck_user_permissions(user: Optional[User]) -> dict:"""    检查用户权限并返回权限字典    返回:        包含各项权限的字典    """# 第一步:用户是否存在# 用 is None 判断(这是唯一该用 is 的场景)if user isNone:return {"can_login": False,"can_vip": False,"discount": 1.0,"message": "用户不存在"        }# 第二步:年龄是否有效(使用链式比较)# 0 < age < 150 是合理的年龄范围ifnot (0 < user.age < 150):return {"can_login": False,"can_vip": False,"discount": 1.0,"message": f"年龄{user.age}无效"        }# 第三步:判断是否成年人(用三元运算符)    is_adult = "成年"if user.age >= 18else"未成年"print(f"用户{user.username}: {is_adult} ({user.age}岁)")# 第四步:根据VIP等级判断权限if user.vip_level == 0:        discount = 1.0        can_vip = True        message = "普通用户"        max_withdraw = 1000elif user.vip_level <= 3:        discount = 1.0 - (user.vip_level * 0.05)  # 95~85折        can_vip = True        message = f"VIP{user.vip_level}用户"        max_withdraw = 10000 * user.vip_levelelse:  # vip_level >= 4        discount = 0.7# 7折        can_vip = False# 已经是最高级        message = "黑钻用户"        max_withdraw = 100000# 第五步:余额判断(多重比较)# 这里不能用链式比较,因为有3个条件if user.balance >= 10000:        priority = "高"elif user.balance >= 1000:        priority = "中"else:        priority = "低"return {"can_login": True,"can_vip": can_vip,"discount": discount,"message": message,"max_withdraw": max_withdraw,"priority": priority,    }defmain():"""主函数:测试权限系统"""print("=== 用户权限判断系统 ===\n")# 创建测试用户    users = [        User("张三", 25, 0, 500, datetime.now()),      # 普通成年用户        User("李四", 17, 2, 2000, datetime.now()),     # 未成年VIP        User("王五", 30, 4, 50000, datetime.now()),    # 黑钻用户        User("赵六", 999, 0, 100, datetime.now()),     # 年龄异常        User(None, None, None, None, None),           # 空用户    ]# 测试每个用户for user in users:print(f"\n--- 测试用户: {user} ---")        result = check_user_permissions(user)print(f"  登录权限: {'✓'if result['can_login'] else'✗'}")print(f"  折扣: {result['discount']:.0%}")print(f"  说明: {result['message']}")print(f"  优先级: {result.get('priority', 'N/A')}")print(f"  最高提现: {result.get('max_withdraw', 'N/A')}")if"message"in result:print(f"  全局消息: {result['message']}")print()if __name__ == "__main__":    main()

运行结果:

=== 用户权限判断系统 ===--- 测试用户: <__main__.User object at 0x7f8c1c104c50> ---用户张三: 成年 (25岁)  登录权限: ✓  折扣: 100%  说明: 普通用户  优先级: 低  最高提现: 1000--- 测试用户: <__main__.User object at 0x7f8c1c104c90> ---用户李四: 未成年 (17岁)  登录权限: ✓  折扣: 90%  说明: VIP2用户  优先级: 中  最高提现: 20000--- 测试用户: <__main__.User object at 0x7f8c1c104cd0> ---用户王五: 成年 (30岁)  登录权限: ✓  折扣: 70%  说明: 黑钻用户  优先级: 高  最高提现: 100000--- 测试用户: <__main__.User object at 0x7f8c1c104d10> ---用户赵六: 成年 (999岁)  登录权限: ✗  折扣: 100%  说明: 年龄999无效  全局消息: 年龄999无效--- 测试用户: <__main__.User object at 0x7f8c1c105050> ---用户None: 无法创建User对象 (需要username)

代码要点总结:

# 第45行:用 is None 判断if user isNone:return {...}# 第53行:链式比较(年龄范围判断)ifnot (0 < user.age < 150):return {...}# 第59行:三元运算符(三行缩成一行)is_adult = "成年"if user.age >= 18else"未成年"# 第63-77行:elif多重判断(VIP等级)if user.vip_level == 0:    ...elif user.vip_level <= 3:    ...else:    ...# 第82-88行:多重比较不能用链式(3个分支)if user.balance >= 10000:    priority = "高"elif user.balance >= 1000:    ...else:    ...

这是一段可以直接套用到你项目里的代码


总结:今天学到了什么?

三个核心要点:

  1. 1. 别再用 is 判断值相等
  • • 判断值用 ==
  • • 只有判断 None 用 is
  1. 2. 理解Truthiness(真值性)
  • • 空值:0, "", [], {}, None 都是 falsy
  • • 判空直接用 if not x:,别写 if x == "" or x == 0:
  1. 3. 能用链式比较,但别迷信链式
  • • 0 <= x <= 100 可以用
  • • 复杂的还是拆开写:x >= 60 and x < 90

今天就可以做的事情

  1. 1. 打开你的项目,搜一下有没有 if x is 10: 这种代码
  • • 有的话,改成 if x == 10:
  1. 2. 检查你的判空逻辑
  • • 如果你还在写 if name == "" or name == None:
  • • 改成 if not name:
  1. 3. 收藏这篇文章
  • • 以后写if判断的时候,回来翻一翻对照着写

下期预告

下一期讲什么

**循环的坑**

for 和 while 怎么选

为什么你的循环跑一次就停了

为什么在循环里改列表会出问题

想看的,关注【Python小甲鱼】,下期见


*本文代码均可直接复制运行,有问题欢迎评论区留言*

最新文章

随机文章