is 比 == 快是因为只比较内存地址,不进行值比较;仅在检查 None、小整数(-5 至 256)等缓存对象时有可测性能优势,但语义错误风险远高于微小提速。

用 is 比 == 快,不是因为它“优化得好”,而是它根本没做值比较——只查两个变量是不是指向同一块内存。这个快,是省事换来的,不是加速得来的。
什么时候is真比==快?
只在极少数场景下有可测量的性能差异:比较 None、小整数(-5 到 256)、短字符串字面量等被 Python 缓存的对象时。is 直接比 id(),== 可能要调用 __eq__()、逐字节比内容、甚至触发类型转换。
-
None是单例,x is None是唯一推荐写法,既安全又快 -
if x is True或is False理论上快,但几乎没必要——布尔值本身极小,==开销可忽略,且语义不如直接写if x: - 对列表、字典、自定义类实例等,
is虽然“快”,但绝大多数时候结果是False,快得毫无意义
is 快的代价:缓存范围外就失效
Python 对小整数(-5 到 256)做了对象复用,所以 100 is 99 + 1 返回 True;但超出这个范围,比如 257 is 256 + 1 就是 False,哪怕值相等。
- 这不是 bug,是 CPython 的实现细节,其他解释器(如 PyPy)行为可能不同
- 拿
is当==用,在 z=512 那种场景下会静默失败——就像你知识库里的 GIS 爬虫例子,逻辑卡死却无报错 - 用
id(a) == id(b)替代a is b并不等价:id()返回的是临时地址标识,对象被销毁重建后地址可能复用,而is是原子性身份判断
为什么== 通常更慢?它到底在干啥
== 不只是“比数字”,它是可被重载的协议:调用左操作数的 __eq__() 方法,而这个方法可以任意复杂。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 列表比较:先比长度,再逐项递归调用
==,遇到嵌套结构开销指数上升 - 浮点数比较:
==严格按 IEEE 754 规则,NaN != NaN,而is对 NaN 会返回False(因为每个 NaN 是独立对象) - 自定义类若没实现
__eq__,默认退化为is行为;但一旦实现,就完全脱离“快”的范畴
真正该关心的不是快慢,而是语义
写 if x is None: 是对的,因为 None 必须是同一个对象;写 if x is 5: 是危险的,因为不能保证 5 总是复用——尤其在函数参数、JSON 解析、数据库读取后,数值大概率是新对象。
- 字符串字面量(如
"hello" is "hello")有时为True,靠的是编译期驻留(interning),但运行时拼接的字符串("hel" + "lo" is "hello")不一定成立 -
is无法替代==做业务逻辑判断,比如用户 ID 是否相等、坐标是否重合、配置项是否匹配 - 工具链(如 mypy、pylint)会警告
is用于非单例/非None场景,这不是矫情,是防踩坑
快慢只是表象,错用 is 的后果不是变慢,而是逻辑在某个边界值上突然不成立——比如从 256 跳到 257,或从测试数据切到真实 API 响应,问题才暴露出来。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










