dict 和 set 在 CPython 中快是因为底层用高度优化的哈希表,平均时间复杂度 O(1),但性能受哈希函数、冲突、内存布局及构造方式等影响;dict.fromkeys() 批量初始化更快;成员检测优先用 set;__slots__ 可节省内存并加速属性访问。
dict 和 set 在 CPython 中快得不像 Python?因为底层用的是哈希表(hash table),且 CPython 实现高度优化:插入、查找、删除平均时间复杂度都是 O(1)。但这个“快”有前提——哈希函数要快,冲突要少,内存布局要友好。
常见误区是以为“只要用 dict 就一定快”,其实构造方式、键类型、扩容时机都会显著影响性能:
dict() 空初始化比 {} 略慢(字节码多一条 CALL_FUNCTION)list)当 dict 键会直接报 TypeError: unhashable type
dict.fromkeys() 成为批量初始化的首选?当你需要一个键存在、值统一的字典(比如去重后标记为 True),dict.fromkeys(iterable, value) 比循环 dict[key] = value 快 2–3 倍,因为它绕过了 Python 层的键值对赋值逻辑,直接在 C 层批量构建哈希表。
注意两个坑:
[]),所有键共享同一个实例 → 改一个全改示例:
valid_keys = ["a", "b", "c"]
flags = dict.fromkeys(valid_keys, False) # ✅ 安全
cache = dict.fromkeys(valid_keys, {}) # ❌ 危险:所有键共用一个 dict
set 而不是 list 做成员检测?只要涉及 if x in container:,且容器长度 > 100,几乎总是该换 set。列表是 O(n) 线性扫描,集合是 O(1) 哈希查找——10 万元素下,前者可能耗时 10ms+,后者稳定在 0.1ms 内。
但别忽略代价:
set 本身要时间:从 list 转 set 是 O(n),如果只查一次,不如直接遍历set 占内存更大:每个元素额外存哈希值 + 更宽松的负载因子(默认 0.625),实际内存占用约是等效 list 的 2–3 倍dict 有序,但 set 依然无序)__slots__ 对自定义类里用 dict 存属性的影响如果你写了一个高频实例化的类,又习

self.__dict__ 动态存属性(比如解析 JSON 后挂载字段),那它的 dict 其实是每个实例独占的一份哈希表。此时开启 __slots__ 能省下每实例 ~50 字节,并加快属性访问——因为绕过了 __dict__ 查找路径。
但要注意限制:
__slots__,实例就不再有 __dict__,不能动态新增未声明的属性__slots__,子类也必须显式定义(哪怕为空 __slots__ = ()),否则报错__dict__(比如用 vars() 或某些 ORM),就不能用 __slots__
典型适用场景:DTO 类、解析后的消息体、高频创建的中间对象。