当前位置: 首页 > news >正文

Python快速入门专业版(十八):Python比较运算符深度解析:从基础判断到对象身份识别(附避坑指南)

在这里插入图片描述

目录

  • 引言:比较运算符——逻辑控制的“决策核心"
  • 常用比较运算符:6种基础关系与多类型适配
    • 1.1 基础类型比较:数值、字符串与复数
      • (1)数值类型比较(int/float)
      • (2)字符串比较(str)
      • (3)复数比较(complex)
    • 1.2 容器类型比较:列表、元组、字典与集合
      • (1)有序容器:列表(list)与元组(tuple)
      • (2)无序容器:字典(dict)与集合(set)
    • 1.3 特殊比较:链式比较与不同类型对比
      • (1)链式比较:简化多条件判断
      • (2)不同类型比较:多数情况不支持
  • 2.核心避坑:`==`与`is`的本质区别(90%新手会错)
    • 2.1 用`id()`函数可视化内存地址
    • 2.2 `__eq__()`方法:决定`==`的判断逻辑
      • 代码示例:自定义对象的`__eq__`重写
    • 2.3 `==`与`is`的使用场景对比(附错误示例)
      • 典型错误场景解析:
  • 3.常见误区与避坑指南
    • 3.1 误区1:用`is`判断容器值是否相等
    • 3.2 误区2:忽视浮点数比较的精度问题
    • 3.3 误区3:认为“空容器 == None”
    • 3.4 误区4:链式比较中混用`and`/`or`
  • 4.实战案例:比较运算符的实际应用
    • 案例1:用户登录验证(多条件比较)
    • 案例2:数据清洗(筛选符合条件的字典)
    • 案例3:自定义对象排序(基于比较的排序)
  • 总结:比较运算符的“三看”原则

引言:比较运算符——逻辑控制的“决策核心"

在Python编程中,几乎所有逻辑分支(if语句)、循环控制(while循环)、数据筛选(列表推导式)都依赖"关系判断"这一基础操作。而实现这一功能的核心工具就是比较运算符。它不仅能判断简单的数值关系(如"10是否大于5")、字符串是否相等这类基础比较,还能处理更复杂的场景,比如判断两个列表的值是否完全一致、变量是否为None等特殊值。

比较运算符作为Python中最基础的逻辑判断工具,其重要性体现在:

  1. 流程控制基础:每个if语句都至少包含一个比较运算
  2. 数据筛选核心:在列表推导式如[x for x in lst if x > 0]中起过滤作用
  3. 对象比较依据:决定自定义类实例如何判断相等性

但新手程序员常陷入两类典型误区:

  1. 概念混淆:分不清"值相等"(==)与"对象相同"(is)的本质区别。例如:

    a = [1,2,3]
    b = a  # b和a指向同一个对象
    c = [1,2,3]  # 新建一个值相同但内存地址不同的列表
    print(a == b)  # True
    print(a is b)  # True 
    print(a == c)  # True(值相同)
    print(a is c)  # False(不同对象)
    

    这种混淆可能导致程序出现隐性bug,特别是在判断None值时,应该总是使用is None而非== None

  2. 类型忽视:不了解不同数据类型(如复数、集合、自定义类)的特殊比较规则。例如:

    print({1,2} == {2,1})  # True(集合无序比较)
    print(1+2j == 2j+1)  # True(复数实部虚部分别比较)
    

本文将从三个层次系统讲解比较运算符:

  1. 基础用法:详解6种比较运算符(==, !=, >, <, >=, <=)的标准行为
  2. 底层原理:剖析==is的本质差异,解释Python的对象标识模型
  3. 实战避坑:通过10+典型代码案例,覆盖数值、字符串、容器、自定义对象等场景

特别地,我们将重点分析以下关键问题:

  • 为什么x is Nonex == None更专业?
  • 如何为自定义类实现有意义的==比较?
  • 浮点数比较时的精度陷阱及解决方案
  • 容器比较时的递归检查机制

通过掌握这些"判断逻辑"的底层原理,你将能够编写出更健壮、更符合Python风格的代码。

常用比较运算符:6种基础关系与多类型适配

Python提供了6种基本的比较运算符,用于比较两个值之间的关系。这些运算符返回布尔值(TrueFalse),但在不同数据类型上的比较行为存在显著差异。理解这些差异对于编写正确的Python代码至关重要。

1.1 基础类型比较:数值、字符串与复数

(1)数值类型比较(int/float)

数值比较是编程中最常见的操作之一,Python支持整数和浮点数之间的比较,且会自动进行类型转换。数值比较遵循数学上的大小关系,值得注意的是浮点数比较存在精度问题。

# 1. 同类型数值比较
print("10 == 10:", 10 == 10)          # True(int与int相等)
print("3.14 > 3.1415:", 3.14 > 3.1415)# False(float精度对比)
print("25 >= 25:", 25 >= 25)          # True(等于满足"大于等于")
print("-5 <= -3:", -5 <= -3)          # True(负数比较:绝对值大的更小)# 2. 跨类型数值比较(int与float)
print("10 == 10.0:", 10 == 10.0)      # True(值相等,类型不同不影响)
print("5 > 5.0:", 5 > 5.0)            # False(值相等,无大小差异)
print("9.9 < 10:", 9.9 < 10)          # True(float与int混合比较)# 3. 浮点数比较的"精度陷阱"(高频坑点)
print("0.1 + 0.2 == 0.3:", 0.1 + 0.2 == 0.3)  # False(浮点数存储误差)
# 解决方案:用"差值绝对值小于极小值"判断
print("abs(0.1+0.2 - 0.3) < 1e-9:", abs(0.1+0.2 - 0.3) < 1e-9)  # True

关键注意

  • 浮点数比较时建议使用math.isclose()函数或差值比较法
  • 跨类型比较时Python会自动进行类型转换

(2)字符串比较(str)

字符串比较遵循字典序(lexicographical order),基于字符的Unicode码点值进行比较。比较过程是从左到右逐个字符对比,直到找到差异或比较完所有字符。

# 1. 基本字符比较
print("'a' < 'b':", 'a' < 'b')        # True(ASCII码97 < 98)
print("'A' < 'a':", 'A' < 'a')        # True(大写字母ASCII码更小)
print("'1' < '9':", '1' < '9')        # True(数字字符按顺序排列)# 2. 多字符比较
print("'apple' < 'banana':", 'apple' < 'banana')  # True(首字符比较)
print("'app' < 'apple':", 'app' < 'apple')        # True(前缀相同,长度短的更小)# 3. 特殊字符比较
print("' ' < 'a':", ' ' < 'a')        # True(空格ASCII码32 < 97)
print("'中' > '国':", '中' > '国')    # True(中文字符按Unicode码点比较)# 4. 大小写敏感比较
print("'Python' == 'python':", 'Python' == 'python')  # False

实用技巧

  • 字符串比较前可先统一大小写:s.lower()或s.upper()
  • 排序时可以使用sorted()函数配合key参数实现复杂排序

(3)复数比较(complex)

复数比较有其特殊性,Python只支持相等性比较,不支持大小比较。这是因为复数在数学上没有自然的排序方式。

# 1. 复数相等性比较
c1 = 3 + 4j
c2 = 3.0 + 4.0j
print(c1 == c2)  # True(实部和虚部分别相等)# 2. 复数不等比较
c3 = 4 + 3j
print(c1 != c3)  # True# 3. 尝试大小比较会报错
try:print(c1 > c3)  # TypeError
except TypeError as e:print(f"错误:{e}")# 4. 特殊情况:虚部为0的复数
real_num = 5
c4 = 5 + 0j
print(real_num == c4)  # True(实部相等,虚部为0)

注意事项

  • 复数比较时实部和虚部都必须相等
  • 复数与实数比较时,虚部必须为0
  • 如需比较复数大小,可比较模:abs(c1) > abs(c2)

1.2 容器类型比较:列表、元组、字典与集合

容器类型(list/tuple/dict/set)仅支持==!=(判断“值是否完全一致”),不支持>/<等大小比较;且不同容器类型(如listtuple)即使元素相同,==也返回False

(1)有序容器:列表(list)与元组(tuple)

需满足“元素数量、顺序、值完全一致”,且类型相同,==才返回True

# 列表比较
list1 = [1, 2, [3, 4]]
list2 = [1, 2, [3, 4]]
list3 = [1, 2, [4, 3]]  # 嵌套列表顺序不同
list4 = (1, 2, [3, 4])  # 类型不同(tuple)print("list1 == list2:", list1 == list2)  # True(数量、顺序、值均一致)
print("list1 == list3:", list1 == list3)  # False(嵌套列表顺序不同)
print("list1 == list4:", list1 == list4)  # False(类型不同)# 元组比较(规则与列表一致)
tuple1 = (10, "hello", (5, 6))
tuple2 = (10, "hello", (5, 6))
tuple3 = (10, "Hello", (5, 6))  # 字符串大小写不同
print("tuple1 == tuple2:", tuple1 == tuple2)  # True
print("tuple1 == tuple3:", tuple1 == tuple3)  # False

关键细节

  • 嵌套容器(如列表中的列表)会递归比较内部元素;
  • 元组与列表即使元素完全相同,因类型不同,==仍返回False

(2)无序容器:字典(dict)与集合(set)

  • 字典:需“键值对完全一致”(键和值均相等),与键的顺序无关(Python 3.7+保留插入顺序,但==仍忽略顺序);
  • 集合:需“元素完全一致”(无顺序、无重复),与元素添加顺序无关。
# 字典比较(键值对一致即可,顺序无关)
dict1 = {"name": "Alice", "age": 25, "hobbies": ["reading"]}
dict2 = {"age": 25, "name": "Alice", "hobbies": ["reading"]}  # 键顺序不同
dict3 = {"name": "Alice", "age": 26, "hobbies": ["reading"]}  # 值不同
print("dict1 == dict2:", dict1 == dict2)  # True
print("dict1 == dict3:", dict1 == dict3)  # False# 集合比较(元素一致即可,顺序无关)
set1 = {1, 2, 3, 4}
set2 = {4, 3, 2, 1}  # 顺序不同
set3 = {1, 2, 3}      # 元素数量不同
print("set1 == set2:", set1 == set2)  # True
print("set1 == set3:", set1 == set3)  # False

注意

  • 字典的==会忽略键的顺序,但需键和值均相等(值的比较遵循对应类型规则,如列表需顺序一致);
  • 集合因无重复元素,{1,1,2}{1,2}相等。

1.3 特殊比较:链式比较与不同类型对比

(1)链式比较:简化多条件判断

Python支持“链式比较”,即多个比较运算符连写,等价于用and连接多个条件,代码更简洁。

# 普通写法(用and连接,冗余)
x = 15
if x > 10 and x < 20:print("x在10~20之间")# 链式比较(更简洁,等价于上述逻辑)
if 10 < x < 20:print("x在10~20之间")  # 输出相同结果# 其他链式比较示例
print("5 <= x <= 15:", 5 <= x <= 15)  # True(x=15,满足两个条件)
print("x > 20 or x < 10:", x > 20 or x < 10)  # False(链式不支持or,需单独写)
print("1 == 1.0 == True:", 1 == 1.0 == True)  # False(等价于1==1.0 and 1.0==True,1.0≠True)

注意:链式比较仅支持“逻辑与(and)”,不支持“逻辑或(or)”;若需或逻辑,需拆分为两个条件。

(2)不同类型比较:多数情况不支持

除“intfloat”外,不同类型(如intstrlistdict)比较大小会直接报错;比较是否相等(==)会返回False(无实际业务意义,不推荐使用)。

# 1. int与str比较(大小报错,相等返回False)
print("10 == '10':", 10 == '10')  # False(值的类型不同,视为不等)
try:print("10 > '10':", 10 > '10')
except TypeError as e:print("不同类型比较错误:", e)  # 输出:'>' not supported between instances of 'int' and 'str'# 2. list与dict比较(相等返回False,大小报错)
print("[1,2] == {'a':1}:", [1,2] == {'a':1})  # False
try:print("[1,2] < {'a':1}:", [1,2] < {'a':1})
except TypeError as e:print("容器类型比较错误:", e)  # 输出:'<' not supported between instances of 'list' and 'dict'

2.核心避坑:==is的本质区别(90%新手会错)

==is是最易混淆的两个“判断符号”,但它们的判断维度完全不同:

  • ==:比较“值是否相等”(关注“内容一致”),本质是调用对象的__eq__()方法;
  • is:比较“内存地址是否相同”(关注“是否为同一个对象”),本质是判断id(a) == id(b)

用一句话总结:“同一个对象必然值相等,但值相等的对象不一定是同一个”

2.1 用id()函数可视化内存地址

id(object)是Python内置函数,返回对象的唯一内存地址标识符(整数)。通过id()可直观看到==is的差异:

# 案例1:小整数池优化(-5~256的整数复用内存)
a = 100
b = 100
c = 257
d = 257print("a == b:", a == b)        # True(值相等)
print("a is b:", a is b)        # True(内存地址相同,100在小整数池内)
print("id(a):", id(a), "id(b):", id(b))  # 输出相同地址,如2898567296528print("c == d:", c == d)        # True(值相等)
print("c is d:", c is d)        # False(257超出小整数池,内存地址不同)
print("id(c):", id(c), "id(d):", id(d))  # 输出不同地址,如2898567550224 vs 2898567550288# 案例2:字符串驻留机制(纯字母/数字/下划线的短字符串复用内存)
s1 = "python123"
s2 = "python123"
s3 = "python 123"  # 含空格,不满足驻留条件
s4 = "python 123"print("s1 == s2:", s1 == s2)    # True(值相等)
print("s1 is s2:", s1 is s2)    # True(短字符串驻留,地址相同)
print("s3 == s4:", s3 == s4)    # True(值相等)
print("s3 is s4:", s3 is s4)    # False(含空格,不驻留,地址不同)# 案例3:容器类型(即使值相同,也创建新对象)
list_a = [1, 2, 3]
list_b = [1, 2, 3]print("list_a == list_b:", list_a == list_b)  # True(值相等)
print("list_a is list_b:", list_a is list_b)  # False(地址不同,列表不复用)
print("id(list_a):", id(list_a), "id(list_b):", id(list_b))  # 不同地址

关键原理

  • Python为节省内存,对“小整数(-5~256)”和“纯字母/数字/下划线的短字符串”做了“缓存复用”(小整数池、字符串驻留),因此相同值的对象可能共享地址;
  • 容器类型(列表、字典、集合)即使值相同,也会创建新对象(无缓存机制),地址不同;
  • 自定义对象默认无缓存,需手动实现(如重写__hash____eq__)才可能复用。

2.2 __eq__()方法:决定==的判断逻辑

==的本质是调用左侧对象的__eq__()方法(如a == b等价于a.__eq__(b))。默认情况下:

  • 内置类型(int/str/list等)的__eq__()已实现“值相等”判断;
  • 自定义对象的__eq__()默认调用父类object的方法,等价于is(比较地址)。

代码示例:自定义对象的__eq__重写

class Student:def __init__(self, student_id, name):self.student_id = student_id  # 学号(唯一标识)self.name = name# 未重写__eq__:默认比较地址
stu1 = Student(2024001, "Alice")
stu2 = Student(2024001, "Alice")
print("未重写__eq__:stu1 == stu2 →", stu1 == stu2)  # False(地址不同)
print("未重写__eq__:stu1 is stu2 →", stu1 is stu2)  # False# 重写__eq__:按学号判断值相等
class StudentEq(Student):def __eq__(self, other):# 先判断other是否为当前类实例if not isinstance(other, StudentEq):return False# 按学号判断相等(忽略姓名差异)return self.student_id == other.student_id# 重写后:==比较学号,is比较地址
stu3 = StudentEq(2024001, "Alice")
stu4 = StudentEq(2024001, "Alicia")  # 姓名不同,学号相同
print("重写__eq__:stu3 == stu4 →", stu3 == stu4)  # True(学号相等)
print("重写__eq__:stu3 is stu4 →", stu3 is stu4)  # False(地址不同)

注意:重写__eq__时,建议同时重写__hash__(哈希值),确保“值相等的对象哈希值相同”(否则无法正常用于集合、字典的键)。

2.3 ==is的使用场景对比(附错误示例)

场景需求推荐使用错误示例(为什么错)正确示例
判断值是否相等(业务核心)==is判断列表:list_a is list_b(即使值相同,也返回False,因地址不同)==判断:list_a == list_b
判断是否为Noneis==判断:x == None(虽能运行,但不规范,None是单例,is更高效)is判断:x is None
判断是否为布尔值单例is==判断:x == True(如1 == True返回True,易混淆“值相等”与“身份相同”)is判断:x is True
判断数值是否在小整数池内isis判断大整数:257 is 257(超出小整数池,返回False,应改用====判断大整数:257 == 257

典型错误场景解析:

# 错误1:用is判断用户输入的年龄是否为18(业务需比较值,却用了身份判断)
age = int(input("请输入年龄:"))
if age is 18:  # 危险!若age是18.0(float),即使值相等,is也返回Falseprint("您刚成年")
else:print("您不是18岁")  # 若输入18.0,会错误输出此句# 正确写法:用==判断值
if age == 18:print("您刚成年")# 错误2:用==判断函数返回是否为None(不规范,且效率低)
def get_user(user_id):return None  # 未找到用户时返回Noneuser = get_user(999)
if user == None:  # 虽能运行,但None是单例,is更高效(直接比较地址)print("未找到用户")# 正确写法:用is判断None
if user is None:print("未找到用户")

3.常见误区与避坑指南

3.1 误区1:用is判断容器值是否相等

容器类型(列表、字典等)即使值完全相同,也会创建新对象(地址不同),用is判断必然返回False,需用==

# 错误
list1 = [1, 2, 3]
list2 = [1, 2, 3]
if list1 is list2:print("列表相同")  # 不执行
else:print("列表不同")  # 错误输出(实际值相同)# 正确
if list1 == list2:print("列表值相同")  # 正确执行

3.2 误区2:忽视浮点数比较的精度问题

0.1 + 0.2因浮点数存储误差,结果为0.30000000000000004,直接用==判断0.1+0.2 == 0.3会返回False。

# 错误
print(0.1 + 0.2 == 0.3)  # False# 正确:用差值绝对值小于极小值
print(abs(0.1 + 0.2 - 0.3) < 1e-9)  # True# 进阶:用decimal模块控制精度
from decimal import Decimal, getcontext
getcontext().prec = 20  # 设置精度为20位
print(Decimal('0.1') + Decimal('0.2') == Decimal('0.3'))  # True

3.3 误区3:认为“空容器 == None”

空容器(如[]""{})是“有值但为空”,None是“无值”,二者==返回False(虽均为假值,但值不同)。

# 错误:认为空列表等于None
if [] == None:print("空列表")  # 不执行# 正确:判断空容器用“隐性布尔值”或`len()`
if not []:  # 空列表是假值,not [] → Trueprint("空列表")  # 正确执行# 区分“空容器”与“None”
data = []  # 有值(空列表)
if data is None:print("无数据")
elif not data:print("有数据,但为空")  # 正确执行

3.4 误区4:链式比较中混用and/or

链式比较仅支持“逻辑与(and)”,若需“逻辑或(or)”,需拆分为两个独立条件。

# 错误:链式比较不支持or
x = 5
if 10 < x < 20 or 0 < x < 5:  # 虽能运行,但易误解为“10<x<(20 or 0)<x<5”print("x在0~5或10~20之间")# 正确:拆分or条件,用括号明确
if (0 < x < 5) or (10 < x < 20):print("x在0~5或10~20之间")  # 正确执行

4.实战案例:比较运算符的实际应用

案例1:用户登录验证(多条件比较)

def login(username, password):"""验证登录:用户名存在且密码正确"""# 模拟数据库用户(用户名小写,密码加密存储,此处简化)valid_users = {"alice": "Alice@123","bob": "Bob@456"}# 1. 判断用户名是否存在(忽略大小写)lower_user = username.lower()if lower_user not in valid_users:return False, "用户名不存在"# 2. 判断密码是否相等(精确比较,区分大小写)if password == valid_users[lower_user]:return True, f"登录成功!欢迎{username}"else:return False, "密码错误"# 测试
test_cases = [("Alice", "Alice@123"),  # 正确用户名+密码("bob", "Bob@4567"),     # 正确用户名+错误密码("Charlie", "123456"),   # 不存在用户名
]for user, pwd in test_cases:success, msg = login(user, pwd)print(f"登录({user}/{pwd}):{msg}")
# 输出:
# 登录(Alice/Alice@123):登录成功!欢迎Alice
# 登录(bob/Bob@4567):密码错误
# 登录(Charlie/123456):用户名不存在

案例2:数据清洗(筛选符合条件的字典)

def filter_products(products, min_price=0, max_price=1000):"""筛选价格在[min_price, max_price]之间的商品"""filtered = []for product in products:# 1. 确保product是字典且含"price"键if not isinstance(product, dict) or "price" not in product:continue# 2. 确保price是数值类型price = product["price"]if not isinstance(price, (int, float)):continue# 3. 比较价格是否在区间内(链式比较)if min_price <= price <= max_price:filtered.append(product)return filtered# 测试数据
products = [{"name": "T恤", "price": 89},{"name": "运动鞋", "price": 299},{"name": "手表", "price": "1500"},  # 价格是字符串,跳过{"name": "袜子", "price": 19},{"name": "背包"},  # 无price键,跳过
]# 筛选10~200元的商品
result = filter_products(products, 10, 200)
print("符合条件的商品:")
for p in result:print(f"- {p['name']}{p['price']}元")
# 输出:
# - T恤:89元
# - 袜子:19元

案例3:自定义对象排序(基于比较的排序)

class Book:def __init__(self, title, author, price):self.title = titleself.author = authorself.price = price# 重写__eq__:按书名和作者判断是否为同一本书def __eq__(self, other):if not isinstance(other, Book):return Falsereturn self.title == other.title and self.author == other.author# 重写__lt__(小于):用于排序(按价格升序)def __lt__(self, other):if not isinstance(other, Book):raise TypeError("无法比较Book与非Book类型")return self.price < other.price# 重写__repr__:打印对象时显示友好信息def __repr__(self):return f"Book(title='{self.title}', author='{self.author}', price={self.price})"# 创建书籍列表
books = [Book("Python编程", "张三", 59.9),Book("Java编程", "李四", 69.9),Book("Python编程", "张三", 59.9),  # 与第一本是“同一本书”Book("C++编程", "王五", 49.9),
]# 1. 判断是否为同一本书(基于__eq__)
book1 = books[0]
book2 = books[2]
print("book1 == book2:", book1 == book2)  # True
print("book1 is book2:", book1 is book2)  # False(地址不同)# 2. 按价格排序(基于__lt__)
books_sorted = sorted(books)
print("按价格升序排序:")
for book in books_sorted:print(book)
# 输出:
# Book(title='C++编程', author='王五', price=49.9)
# Book(title='Python编程', author='张三', price=59.9)
# Book(title='Python编程', author='张三', price=59.9)
# Book(title='Java编程', author='李四', price=69.9)

总结:比较运算符的“三看”原则

掌握比较运算符的核心是建立“三看”判断逻辑,避免99%的误区:

  1. 看需求:比"内容"还是比"身份"

    • 业务逻辑中判断"值是否一致"(如用户年龄是否为18、列表元素是否相同):用==
      • 示例:user_age == 18判断数值相等,["a", "b"] == ["a", "b"]判断列表内容相同
      • 应用场景:数据校验、表单提交检查、API响应比对
    • 底层判断"是否为同一个对象"(如是否为None、是否为布尔值单例):用is
      • 示例:result is None判断空值,flag is True判断布尔值
      • 应用场景:单例模式、空值检查、缓存对象比对
  2. 看对象:是"普通类型"还是"特殊对象"

    • 普通类型(int、str、list等):
      • ==比内容:123 == 123为True,"hello" == "hello"为True
      • is比地址:a = [1,2]; b = [1,2]; a is b为False(不同对象)
    • 单例对象(None、True、False):
      • 只能用is判断(因全程序唯一)
      • 错误示例:None == None虽然为True,但不符合PEP8规范
    • 自定义对象:
      • 未重写__eq__时:==等价于is,仅比较内存地址
      • 重写__eq__后:可按业务逻辑定义内容相等性
      • 示例:
        class Person:def __init__(self, name):self.name = namedef __eq__(self, other):return self.name == other.name
        
  3. 看场景:是否有"特殊规则"

    • 浮点数处理:
      • 避免直接==0.1 + 0.2 == 0.3返回False
      • 正确做法:abs(a - b) < 1e-9或使用math.isclose()
    • 容器类型比较:
      • ==要求元素数量、顺序、值完全一致
        • 示例:[1, 2] == [2, 1]为False
      • is要求内存地址相同
        • 示例:a = [1]; b = a; a is b为True
    • 链式比较:
      • 仅支持and逻辑:1 < x < 10等价于1 < x and x < 10
      • or逻辑时必须拆分:x < 1 or x > 10
    • 特殊场景:
      • 字符串驻留:小字符串is可能为True但不建议依赖
      • 不可变对象:相同值的is可能为True但不保证

通过这一原则,你能精准选择合适的比较方式,写出逻辑清晰、无隐性bug的代码,让"判断"成为编程中的"确定性工具",而非"踩坑点"。实际应用时建议:

  1. 业务数据比较优先用==
  2. 单例对象必须用is
  3. 浮点比较用误差范围
  4. 自定义类实现__eq__
  5. 避免依赖实现细节的is比较

文章转载自:

http://AWlZFsgv.qyLLw.cn
http://kMnnXYPV.qyLLw.cn
http://PzSLY7V9.qyLLw.cn
http://iO2cKbJm.qyLLw.cn
http://ds2dwykm.qyLLw.cn
http://rtKCL2ly.qyLLw.cn
http://tw0VXQat.qyLLw.cn
http://7P7Dncil.qyLLw.cn
http://biZEF5Fa.qyLLw.cn
http://33LBsJfR.qyLLw.cn
http://4aEMkqFC.qyLLw.cn
http://BGN0QUbS.qyLLw.cn
http://cLA0B0GN.qyLLw.cn
http://4NRXGI6j.qyLLw.cn
http://lvu2odAK.qyLLw.cn
http://5R6cfj2T.qyLLw.cn
http://xfknjU5a.qyLLw.cn
http://1bgiS31B.qyLLw.cn
http://mdU8pQJk.qyLLw.cn
http://TIYOIzQ3.qyLLw.cn
http://lAdneIDk.qyLLw.cn
http://OM4eVPNx.qyLLw.cn
http://rvwLTi6K.qyLLw.cn
http://sp3fwTHW.qyLLw.cn
http://CgE3rowq.qyLLw.cn
http://LKY0HX2X.qyLLw.cn
http://tsJGaVdE.qyLLw.cn
http://eu2niOIp.qyLLw.cn
http://XSxk1ER0.qyLLw.cn
http://WlJW9sjf.qyLLw.cn
http://www.dtcms.com/a/376592.html

相关文章:

  • 微服务网关实战:从三次灾难性故障到路由与权限的体系化防御
  • 从C++开始的编程生活(8)——内部类、匿名对象、对象拷贝时的编译器优化和内存管理
  • 【AI时代速通QT】第六节:Qt Creator从添加新窗口到项目构建运行配置
  • 【CVPR 2022】面向2020年代的卷积神经网络
  • 图神经网络介绍
  • FPGA入门到进阶:可编程逻辑器件的魅力
  • 【解决问题】Ubuntu18上无法运行arm-linux-gcc
  • 嵌入式学习day47-硬件-imx6ull-LED
  • 深入体验—Windows从零到一安装KingbaseES数据库
  • 力扣习题——电话号码的字母组合
  • Linux环境下爬虫程序的部署难题与系统性解决方案
  • 深入解析ThreadLocal:线程数据隔离利器
  • D01-【计算机二级】Python(1)基本操作第41题
  • API开发工具postman、国内xxapi和SmartApi的性能对比
  • Scikit-learn Python机器学习 - 分类算法 - 线性模型 逻辑回归
  • SciKit-Learn 全面分析 digits 手写数据集
  • 《sklearn机器学习——数据预处理》标准化或均值去除和方差缩放
  • 保序回归Isotonic Regression的sklearn实现案例
  • 《sklearn机器学习——数据预处理》离散化
  • 无人机桨叶转速技术要点与突破
  • GPFS存储服务如何使用及运维
  • ELK 日志采集与解析实战
  • BI数据可视化:驱动数据价值释放的关键引擎
  • FinChat-金融领域的ChatGPT
  • OpenTenBase日常操作锦囊(新手上路DML)
  • Dart 中的 Event Loop(事件循环)
  • C++/Java编程小论——方法设计与接口原则总结
  • Java-Spring入门指南(四)深入IOC本质与依赖注入(DI)实战
  • 线扫相机采集图像起始位置不正确原因总结
  • JVM 对象创建的核心流程!