Python基础指南之比较运算符的使用技巧详解
一、开篇:比较——编程世界的"判断题"
如果说编程是让计算机帮我们做决策,那么比较运算就是决策的起点。每一次if判断、每一次循环控制,背后都离不开比较运算符的身影。它们就像编程世界里的"判断题",返回的不是"对"就是"错"——也就是True或False。
先来看一段代码,感受一下比较运算符的日常:
age = 25
if age >= 18:
print("你已经成年了!")
score = 85
if score == 100:
print("满分!太棒了!")
elif score >= 60:
print("及格了,继续加油!")
else:
print("需要补考哦。")
上面这段代码中,>=、==这些符号就是比较运算符。它们看似简单,但Python的比较运算符有一些非常优雅的特性——比如链式比较,这是很多其他语言不具备的语法糖,用好了能让你的代码简洁又易读。
今天这篇文章,我们就来全面掌握Python比较运算符的每一个细节,从基础用法到高级技巧,让你写出的判断逻辑既准确又优雅。
二、Python的比较运算符全家福
2.1 六大比较运算符一览
Python共提供了6种比较运算符:
# Python的6种比较运算符 x = 10 y = 20 # 1. 等于 == —— 判断两个值是否相等 print(x == y) # False print(x == 10) # True # 2. 不等于 != —— 判断两个值是否不相等 print(x != y) # True print(x != 10) # False # 3. 大于 > —— 判断左边是否大于右边 print(x > y) # False print(x > 5) # True # 4. 小于 < —— 判断左边是否小于右边 print(x < y) # True print(x < 5) # False # 5. 大于等于 >= —— 判断左边是否大于或等于右边 print(x >= 10) # True print(x >= y) # False # 6. 小于等于 <= —— 判断左边是否小于或等于右边 print(x <= 10) # True print(x <= y) # True
2.2 比较运算符的返回值
每一个比较运算的结果都是布尔值——True或False:
result = (10 > 5)
print(result) # True
print(type(result)) # <class 'bool'>
# 比较结果可以直接用于条件判断
if 10 > 5:
print("10确实大于5") # 这行会执行
# 也可以赋值给变量,用于后续逻辑
is_adult = age >= 18
is_pass = score >= 60
has_permission = is_adult and is_pass
2.3 比较运算符适用哪些数据类型
比较运算符不仅能比较数字,还能比较很多其他类型:
# 1. 数值类型(int, float, complex的实部比较)
print(10 > 3.5) # True —— int和float可以混用
print(3.14 < 3.15) # True
# 2. 字符串 —— 按字典序(Unicode码点)逐字符比较
print("apple" < "banana") # True —— 'a'的码点小于'b'
print("abc" < "abd") # True —— 前两个字符相同,'c' < 'd'
print("abc" == "abc") # True
print("A" < "a") # True —— 大写字母码点小于小写
print("100" < "20") # True —— 字符串比较!'1' < '2',不是数值比较!
# 3. 列表、元组 —— 逐元素比较
print([1, 2, 3] == [1, 2, 3]) # True
print([1, 2, 3] < [1, 2, 4]) # True —— 第三个元素3 < 4
print([1, 2] < [1, 2, 3]) # True —— 前面相同,短的更小
print((1, 2) < (1, 3)) # True
# 4. 集合 —— 子集/超集关系
print({1, 2} < {1, 2, 3}) # True —— 真子集
print({1, 2} <= {1, 2}) # True —— 子集(允许相等)
注意:并非所有类型之间都能互相比较。不同类型之间比较可能会引发TypeError:
# print(10 < "20") # TypeError: '<' not supported between instances of 'int' and 'str'
# print([1,2] < 3) # TypeError
# print({1,2} < [1,2]) # TypeError
三、深入理解 == 与 !=
3.1 == 调用的是eq方法
当你写a == b时,Python底层实际上调用的是a.__eq__(b):
# a == b 等价于 a.__eq__(b)
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
"""自定义相等比较的逻辑"""
if isinstance(other, Person):
return self.name == other.name and self.age == other.age
return False
p1 = Person("张三", 25)
p2 = Person("张三", 25)
p3 = Person("李四", 30)
print(p1 == p2) # True —— 因为我们的__eq__比较了name和age
print(p1 == p3) # False
如果不自定义__eq__,默认的==比较的是对象的内存地址(和is一样):
class Simple:
pass
s1 = Simple()
s2 = Simple()
print(s1 == s2) # False —— 没有__eq__,比较的是id
print(s1 is s2) # False
3.2 != 调用的是ne方法
!=对应的是__ne__方法。默认情况下,a != b等价于not (a == b),除非你显式定义了__ne__:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
if isinstance(other, Person):
return self.name == other.name and self.age == other.age
return False
def __ne__(self, other):
"""如果不定义,!= 会自动取 == 的反值"""
result = self.__eq__(other)
if result is NotImplemented:
return result
return not result
p1 = Person("张三", 25)
p2 = Person("张三", 25)
print(p1 != p2) # False —— 因为它们相等
3.3 == 与 is 的区别(关键知识点)
这是一个高频面试题,也是初学者最容易踩的坑:
# == 比较的是"值"
# is 比较的是"身份"(是否是同一个对象)
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True —— 值相等
print(a is b) # False —— 但不是同一个对象
print(a is c) # True —— c就是a,同一个对象
# 生活中的类比:
# == :这两张100元钞票的购买力相同吗?
# is :这是同一张钞票吗?
# 小整数缓存(-5到256)会让is的行为出乎意料
x = 256
y = 256
print(x is y) # True —— Python缓存了小整数对象
x = 257
y = 257
print(x is y) # False —— 超出了缓存范围!
# 📝 最佳实践:比较值用 ==,比较None用 is
if name is None: # ✅ 推荐
print("名字未设置")
if name == None: # ⚠️ 不推荐(虽然也能用)
print("名字未设置")
四、大于、小于与字典序比较
4.1 字符串的字典序比较
字符串比较遵循字典序(lexicographic order),也就是从左到右逐个字符比较其Unicode码点:
# ord()函数查看字符的Unicode码点
print(ord('a')) # 97
print(ord('b')) # 98
print(ord('A')) # 65
print(ord('0')) # 48
# 逐字符比较过程
# "apple" vs "banana"
# 'a'(97) < 'b'(98) → True,直接返回,不比较后面的字符
print("apple" < "banana") # True
# 更仔细的逐字符比较
def compare_strings(s1, s2):
"""手动模拟字符串比较过程"""
for i, (c1, c2) in enumerate(zip(s1, s2)):
print(f"位置{i}: '{c1}'({ord(c1)}) vs '{c2}'({ord(c2)})")
if c1 < c2:
print(f"→ '{c1}' < '{c2}',结果:{s1} < {s2}")
return
elif c1 > c2:
print(f"→ '{c1}' > '{c2}',结果:{s1} > {s2}")
return
# 所有字符都相同,比较长度
if len(s1) < len(s2):
print(f"→ 前缀相同,{s1}更短,结果:{s1} < {s2}")
elif len(s1) > len(s2):
print(f"→ 前缀相同,{s2}更短,结果:{s1} > {s2}")
else:
print(f"→ 完全相同,结果:{s1} == {s2}")
compare_strings("abc", "abd")
# 位置2: 'c'(99) vs 'd'(100)
# → 'c' < 'd',结果:abc < abd
print("-" * 40)
compare_strings("abc", "abc")
# → 完全相同,结果:abc == abc
print("-" * 40)
compare_strings("abc", "ab")
# → 前缀相同,ab更短,结果:abc > ab
4.2 常用字符串比较场景
# 1. 版本号比较(简单情况)
def is_newer_version(v1, v2):
"""比较两个版本号,v1是否比v2新"""
parts1 = [int(x) for x in v1.split('.')]
parts2 = [int(x) for x in v2.split('.')]
return parts1 > parts2 # 列表逐元素比较!
print(is_newer_version("3.10.1", "3.9.8")) # True
print(is_newer_version("2.0.0", "2.0.1")) # False
# 2. 按字母顺序排序
names = ["张三", "李四", "apple", "Banana", "中文"]
print(sorted(names))
# ['Banana', 'apple', '张三', '李四', '中文']
# 大写字母 < 小写字母 < 中文(按Unicode码点)
# 3. Python风格的字符串排序(忽略大小写)
words = ["apple", "Banana", "Cherry", "date"]
print(sorted(words, key=str.lower))
# ['apple', 'Banana', 'Cherry', 'date']
# 4. 判断字符串是否为有效的数字范围
def is_between(s, low, high):
"""判断字符串s是否在low和high之间(字典序)"""
return low <= s <= high
print(is_between("cat", "apple", "dog")) # True
print(is_between("zebra", "apple", "dog")) # False
4.3 列表和元组的逐元素比较
这是Python非常强大的特性——复合数据结构的逐元素比较:
# 列表比较规则:从索引0开始逐元素比较
# 1. 找到第一个不同的位置,比较该位置的元素
# 2. 如果所有对应位置都相同,则较短的列表"更小"
# 3. 对应位置的元素必须可比较
print([1, 2, 3] > [1, 2, 2]) # True —— 第三个元素3 > 2
print([1, 2] < [1, 2, 0]) # True —— 前缀相同,短的更小
print([1, 2, 3] == [1, 2, 3]) # True
print([] < [0]) # True —— 空列表小于任何非空列表
# 这个特性在实际开发中非常有用
# 示例1:按多个条件排序
students = [
("张三", 85, 18),
("李四", 85, 17),
("王五", 90, 19),
("赵六", 85, 17),
]
# 按成绩降序、年龄升序排序
# 因为我们希望成绩高的排前面,所以用负号
sorted_students = sorted(students, key=lambda s: (-s[1], s[2], s[0]))
for s in sorted_students:
print(f"{s[0]}: 成绩{s[1]}, 年龄{s[2]}")
# 示例2:判断时间段是否重合
def has_overlap(start1, end1, start2, end2):
"""两个时间段是否有重叠"""
# 时间段用元组(start, end)表示,可以直接比较
return start1 < end2 and start2 < end1
print(has_overlap((9, 12), (10, 14))) # True
print(has_overlap((9, 10), (10, 12))) # False
五、链式比较:Python的独门绝技
5.1 什么是链式比较
这是Python最优雅的特性之一。在大部分语言中,要判断一个值是否在某个区间内,你需要这样写:
// Java或C语言风格
if (x >= 0 && x <= 100) {
// x在0到100之间
}
而在Python中,你可以写出几乎和数学表达式一样的代码:
x = 50
if 0 <= x <= 100:
print("x在0到100之间") # 数学上写法的直接翻译!
这就是链式比较(chained comparison)。Python允许你将多个比较运算符串联起来,它的含义和你直觉所想完全一致。
5.2 链式比较的底层原理
链式比较的底层实现非常精妙。当你写:
a < b < c
Python实际解析为:
(a < b) and (b < c)
但有一个关键区别:中间表达式只计算一次!
# 假设有一个有副作用的函数
def get_value():
print("计算值...")
return 10
# 链式比较
result = 5 < get_value() < 20
# 输出:"计算值..."(只输出一次!)
# 等价于
temp = get_value()
result = (5 < temp) and (temp < 20)
# 而不是:result = (5 < get_value()) and (get_value() < 20) ← 这会调用两次!
这在实际开发中非常重要,特别是当中间表达式涉及函数调用或属性访问时:
# ✅ 好的写法:链式比较,user.age只计算一次
if 0 <= user.age <= 120:
print("年龄合法")
# ✅ 等价于手动写法
age = user.age
if 0 <= age and age <= 120:
print("年龄合法")
# 用and也可以,但要注意user.age会计算两次
if 0 <= user.age and user.age <= 120:
print("年龄合法") # 对于简单属性访问,影响不大
5.3 链式比较的各种组合
链式比较可以混合使用不同的比较运算符:
x = 10 # 1. 区间判断 print(0 <= x <= 100) # True —— x在[0, 100]内 print(0 < x <= 100) # True —— x在(0, 100]内 print(0 <= x < 10) # False —— x在[0, 10)内 # 2. 判断是否相等 a = b = 5 print(a == b == 5) # True —— a等于b且b等于5 c = 10 print(a == b == c) # False —— a等于b(5==5),但b不等于c(5≠10) # 3. 递减序列 print(5 > x > 0) # False —— 5 > 10 为 False print(100 > x > 5) # True # 4. 复杂组合(不常见但合法) print(1 < 3 > 2) # True —— 1 < 3 and 3 > 2 print(1 < 3 < 5 > 4 > 2) # True —— 所有相邻比较都为True # 5. 包含 != 的链式比较 print(1 != 2 != 3) # True —— 1 != 2 and 2 != 3 print(1 != 2 != 1) # True —— 1 != 2 and 2 != 1(注意,2 != 1 True)
5.4 链式比较的常见应用场景
# 场景1:成绩等级判断
score = 85
if 90 <= score <= 100:
grade = "优秀"
elif 80 <= score < 90:
grade = "良好"
elif 70 <= score < 80:
grade = "中等"
elif 60 <= score < 70:
grade = "及格"
else:
grade = "不及格"
print(f"成绩{score} → {grade}")
# 场景2:时间范围验证
hour = 14
if 9 <= hour < 18:
print("工作时间")
elif 18 <= hour < 22:
print("晚间时段")
else:
print("休息时间")
# 场景3:坐标范围检测
x, y = 5, 8
if 0 <= x <= 10 and 0 <= y <= 10:
print(f"点({x}, {y})在矩形区域内")
# 场景4:用户名长度验证
username = "python_master"
if 3 <= len(username) <= 20:
print("用户名长度合法")
else:
print("用户名长度应在3到20个字符之间")
# 场景5:温度报警系统
def check_temperature(temp):
if temp < 0:
return "❄️ 冰冻警告!"
elif 0 <= temp < 10:
return "🥶 寒冷"
elif 10 <= temp < 25:
return "😊 舒适"
elif 25 <= temp < 35:
return "🌞 温暖"
elif 35 <= temp < 45:
return "🔥 高温警告!"
else:
return "☠️ 极端温度!"
for t in [-5, 5, 20, 30, 40, 50]:
print(f"{t}°C: {check_temperature(t)}")
六、浮点数比较的特殊处理
6.1 为什么不能直接用 == 比较浮点数
这是几乎所有编程语言都会遇到的问题:
# 经典案例 print(0.1 + 0.2) # 0.30000000000000004 —— 不是精确的0.3! print(0.1 + 0.2 == 0.3) # False! # 原因:0.1和0.2在二进制中是无限循环小数 # 就像十进制中 1/3 = 0.3333... # 计算机只能用有限位二进制近似表示 # 更多令人惊讶的例子 print(0.3 == 0.1 + 0.2) # False print(0.5 == 0.25 + 0.25) # True(0.5可以被精确表示)
6.2 正确的浮点数比较方式
import math
# 方法1:使用math.isclose() —— 推荐!
print(math.isclose(0.1 + 0.2, 0.3)) # True
print(math.isclose(0.1 + 0.2, 0.3, rel_tol=1e-9)) # True
# math.isclose()的参数
# rel_tol: 相对容差(默认1e-9)
# abs_tol: 绝对容差(默认0.0)
print(math.isclose(1e-8, 2e-8, rel_tol=0.5)) # True —— 相对差50%
print(math.isclose(1e-8, 2e-8, abs_tol=1e-7)) # True —— 绝对差1e-8 < 1e-7
# 方法2:自定义容差比较
def approx_equal(a, b, tolerance=1e-9):
"""判断两个浮点数是否近似相等"""
return abs(a - b) < tolerance
print(approx_equal(0.1 + 0.2, 0.3)) # True
print(approx_equal(0.1 + 0.2, 0.3, 1e-15)) # False —— 容差太小
# 方法3:使用decimal模块进行精确比较
from decimal import Decimal
d1 = Decimal('0.1') + Decimal('0.2')
d2 = Decimal('0.3')
print(d1 == d2) # True —— 精确的十进制运算!
# 但是Decimal也更慢,适用于金融等对精度有严格要求的场景
# 方法4:对于整数运算的结果,可以直接比较
print(1.0 + 2.0 == 3.0) # True —— 这些值可以被精确表示
6.3 浮点数比较的最佳实践
import math
# ✅ 推荐做法
def compare_floats(a, b, operation='eq', tolerance=1e-9):
"""安全的浮点数比较"""
if operation == 'eq':
return math.isclose(a, b, abs_tol=tolerance)
elif operation == 'lt':
return a < b and not math.isclose(a, b, abs_tol=tolerance)
elif operation == 'le':
return a < b or math.isclose(a, b, abs_tol=tolerance)
elif operation == 'gt':
return a > b and not math.isclose(a, b, abs_tol=tolerance)
elif operation == 'ge':
return a > b or math.isclose(a, b, abs_tol=tolerance)
else:
raise ValueError(f"Unknown operation: {operation}")
# 测试
x = 0.1 + 0.2
y = 0.3
print(f"x == y: {compare_floats(x, y, 'eq')}") # True
print(f"x < y: {compare_floats(x, y, 'lt')}") # False
print(f"x <= y: {compare_floats(x, y, 'le')}") # True
print(f"x > y: {compare_floats(x, y, 'gt')}") # False
print(f"x >= y: {compare_floats(x, y, 'ge')}") # True
七、比较运算符与其他运算符的区别
7.1 比较 vs 赋值
这是初学者最容易混淆的两个符号:
# = 是赋值运算符
# == 是比较运算符(等于)
x = 10 # 赋值:把10存入变量x
x == 10 # 比较:x的值是否等于10?返回True
# 常见错误
# if x = 10: # SyntaxError!=是赋值,不能用在if中
# print(x)
if x == 10: # ✅ 正确:比较x是否等于10
print(x)
# 海象运算符 := (Python 3.8+) —— 在表达式中赋值
# 这个不是比较运算符!
if (n := len("hello")) > 3:
print(f"字符串长度{n}大于3")
# 一句话总结:
# = 赋值
# == 比较(等于)
# := 表达式内赋值(海象运算符)
7.2 比较 vs 成员 vs 身份
三种运算符各司其职:
# 比较运算符:比较值的大小关系
# ==, !=, >, <, >=, <=
# 成员运算符:判断是否在容器中
# in, not in
print('a' in 'abc') # True
print(3 in [1, 2, 3, 4]) # True
# 身份运算符:判断是否为同一对象
# is, is not
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True —— 值相同
print(a is b) # False —— 不是同一对象
# 三者结合起来使用
def validate_input(value, valid_range, valid_set):
"""综合验证输入"""
if value is None:
return False, "值不能为None"
if not (valid_range[0] <= value <= valid_range[1]):
return False, f"值不在合法范围{valid_range}内"
if value not in valid_set:
return False, f"值不在允许的集合{valid_set}中"
return True, "验证通过"
print(validate_input(5, (0, 10), {1, 3, 5, 7, 9}))
# (True, '验证通过')
print(validate_input(6, (0, 10), {1, 3, 5, 7, 9}))
# (False, "值不在允许的集合{1, 3, 5, 7, 9}中")
八、实战案例
8.1 密码强度检测器
def check_password_strength(password):
"""检测密码强度,返回评分和建议"""
score = 0
suggestions = []
# 检查长度
if len(password) < 6:
suggestions.append("密码太短,至少需要6个字符")
elif 6 <= len(password) < 10:
score += 1
elif 10 <= len(password) < 16:
score += 2
else:
score += 3
# 检查是否包含大写字母
has_upper = any('A' <= c <= 'Z' for c in password)
if has_upper:
score += 1
else:
suggestions.append("建议添加大写字母")
# 检查是否包含小写字母
has_lower = any('a' <= c <= 'z' for c in password)
if has_lower:
score += 1
else:
suggestions.append("建议添加小写字母")
# 检查是否包含数字
has_digit = any('0' <= c <= '9' for c in password)
if has_digit:
score += 1
else:
suggestions.append("建议添加数字")
# 检查是否包含特殊字符
special_chars = set("!@#$%^&*()_+-=[]{}|;:,.<>?")
has_special = any(c in special_chars for c in password)
if has_special:
score += 2
else:
suggestions.append("建议添加特殊字符")
# 评分等级
if score <= 2:
strength = "弱 🚫"
elif 3 <= score <= 5:
strength = "中等 ⚠️ "
elif 6 <= score <= 7:
strength = "强 ✅"
else:
strength = "非常强 🛡️"
return strength, score, suggestions
# 测试
passwords = ["123456", "abc123", "Abc123!@", "MyP@ssw0rd2024!", "a"]
for pwd in passwords:
strength, score, suggestions = check_password_strength(pwd)
print(f"\n密码: {pwd}")
print(f"强度: {strength} (得分: {score})")
if suggestions:
for s in suggestions:
print(f" 💡 {s}")
8.2 成绩管理系统中的等级评定
def calculate_grade(scores):
"""计算总成绩和等级"""
if not scores:
return 0, "无成绩"
total = sum(scores)
average = total / len(scores)
# 使用链式比较评定等级
if 90 <= average <= 100:
grade = "A+"
comment = "🌟 卓越!继续保持!"
elif 85 <= average < 90:
grade = "A"
comment = "👏 优秀!"
elif 80 <= average < 85:
grade = "B+"
comment = "👍 良好偏上"
elif 75 <= average < 80:
grade = "B"
comment = "🙂 良好"
elif 70 <= average < 75:
grade = "C+"
comment = "📚 中等偏上,还有提升空间"
elif 60 <= average < 70:
grade = "C"
comment = "✏️ 及格,需要更加努力"
else:
grade = "F"
comment = "📖 不及格,请认真复习"
return average, grade, comment
# 批量处理学生成绩
students = {
"张三": [95, 88, 92, 97, 90],
"李四": [78, 82, 80, 75, 79],
"王五": [60, 65, 58, 62, 55],
"赵六": [45, 52, 48, 50, 55],
}
for name, scores in students.items():
avg, grade, comment = calculate_grade(scores)
print(f"{name}: 平均分={avg:.1f}, 等级={grade}, {comment}")
8.3 IP地址范围检测
def ip_to_tuple(ip):
"""将IP地址字符串转换为整数元组"""
return tuple(int(part) for part in ip.split('.'))
def is_ip_in_range(ip, start_ip, end_ip):
"""判断IP是否在指定范围内(使用链式比较的列表版)"""
ip_tuple = ip_to_tuple(ip)
start_tuple = ip_to_tuple(start_ip)
end_tuple = ip_to_tuple(end_ip)
# 元组的逐元素比较使得IP范围判断非常简单!
return start_tuple <= ip_tuple <= end_tuple
# 测试
print(is_ip_in_range("192.168.1.50", "192.168.1.1", "192.168.1.100")) # True
print(is_ip_in_range("192.168.2.1", "192.168.1.1", "192.168.1.254")) # False
print(is_ip_in_range("10.0.0.5", "10.0.0.0", "10.0.0.255")) # True
九、常见陷阱与最佳实践
9.1 陷阱1:字符串与数字的"比较"
# ⚠️ Python 3中不能直接比较不同类型
# print("10" > 5) # TypeError
# 但有些意想不到的情况
print("10" > "5") # False!因为字符串比较:'1' < '5'
print(10 > 5) # True —— 数值比较
# 📝 确保比较时类型一致
def safe_compare(a, b):
"""安全的比较函数——要求类型一致"""
if type(a) != type(b):
raise TypeError(f"不能比较{type(a).__name__}和{type(b).__name__}")
return a > b
# 或者先转换类型
a_str = "10"
b_int = 5
print(int(a_str) > b_int) # True —— 明确转换后比较
9.2 陷阱2:NaN的比较特性
# NaN(Not a Number)的比较行为非常特殊
import math
nan = float('nan')
print(nan == nan) # False —— NaN不等于任何值,包括自身!
print(nan != nan) # True
print(nan > 0) # False
print(nan < 0) # False
# 判断NaN的正确方式
print(math.isnan(nan)) # True —— ✅ 推荐方式
# 这在数据处理中非常重要
data = [1.0, 2.0, float('nan'), 3.0, float('nan')]
# 去除NaN值
clean_data = [x for x in data if not math.isnan(x)]
print(clean_data) # [1.0, 2.0, 3.0]
# 注意:NaN可以导致排序异常
# sorted([1.0, float('nan'), 2.0]) # 在不同Python版本中行为不同
9.3 陷阱3:None的比较
# ✅ 推荐:使用 is 比较 None
x = None
if x is None: # 推荐
print("x是None")
if x is not None: # 推荐
print("x不是None")
# ⚠️ 不推荐:使用 == 比较 None
if x == None: # 可以工作,但不推荐
print("x是None")
# 原因:== 可以被自定义的 __eq__ 覆盖
class Weird:
def __eq__(self, other):
return True # 疯狂的__eq__:和任何值比较都返回True
w = Weird()
print(w == None) # True —— 但实际上w并不是None!
print(w is None) # False —— is不会被覆盖,这才是真实情况
# 📝 铁律:比较None永远用 is / is not
9.4 最佳实践总结
# 最佳实践对照表
# 1. 区间判断 → 用链式比较
# ✅
if 0 <= x <= 100:
pass
# ❌
if x >= 0 and x <= 100:
pass
# 2. 浮点数比较 → 用math.isclose()
# ✅
import math
if math.isclose(a, b):
pass
# ❌
if a == b: # 对于浮点数不安全
pass
# 3. None判断 → 用is
# ✅
if x is None:
pass
# ❌
if x == None:
pass
# 4. 类型判断 → 用isinstance()
# ✅
if isinstance(x, str):
pass
# ❌
if type(x) == str:
pass
# 5. 真值判断 → 利用Python的真值规则
# ✅
if my_list: # 非空列表为True
pass
# ❌
if len(my_list) > 0:
pass
# ✅
if name: # 非空字符串为True
pass
# ❌
if name != "":
pass
十、本章小结
本文我们系统性地学习了Python比较运算符的方方面面:
- 六大比较运算符:
==(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)、<=(小于等于),每个都返回布尔值。 - == 与 != 的底层:
==调用__eq__方法,!=调用__ne__方法,可以自定义比较逻辑。 - == 与 is 的区别:
==比较值,is比较身份(内存地址)。比较None永远用is。 - 字典序比较:字符串和列表/元组都支持逐元素比较,这是Python非常实用的特性。
- 链式比较:Python独有语法
a < b < c,等价于(a < b) and (b < c),且中间表达式只计算一次。这是写出优雅Python代码的必备技能。 - 浮点数比较:永远不要直接用
==比较浮点数,使用math.isclose()或自定义容差。 - 常见陷阱:不同类型不能比较、NaN不等于自身、None应该用
is比较。
比较运算符虽然简单,但它们是构建条件判断逻辑的基石。掌握这些细节和最佳实践,能让你写出更健壮、更优雅的Python代码。
以上就是Python基础指南之比较运算符的使用技巧详解的详细内容,更多关于Python比较运算符的资料请关注脚本之家其它相关文章!
相关文章
利用PyQt5+Matplotlib 绘制静态/动态图的实现代码
这篇文章主要介绍了利用PyQt5+Matplotlib 绘制静态/动态图的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-07-07


最新评论