Python标准库无有序集合,SortedSet(sortedcontainers)支持排序顺序的高效集合运算,OrderedSet可自定义插入顺序;二者均不替代list索引用途。

Python 标准库没有“有序集合”(ordered set)的内置类型,set 无序、list 支持顺序但去重低效——想做交/并/差等运算还保持插入顺序或排序顺序,必须借助第三方库或小心封装。
为什么不能直接用 sorted(set(...)) 做有序集合运算
看似简单,实则破坏“集合语义”和“动态有序性”:
-
sorted(set(a))每次都丢弃原顺序,只按值排序,无法保留插入顺序(比如你希望先添加的元素优先) - 结果是
list,不支持&、|、-等集合操作符,后续再算交集就得转回set再转回list,顺序又丢了 - 多次运算后无法高效去重——
list(set(...))不保序,dict.fromkeys(...)保序但不支持集合运算 - 性能差:每次运算都要重建结构,O(n) 构建 + O(n log n) 排序,而真正有序集合应支持 O(log n) 插入/查找
用 SortedSet(来自 sortedcontainers)做真·有序集合运算
SortedSet 是纯 Python 实现、无需编译、API 兼容 set,且底层用分块列表维持排序,支持高效增删查和标准集合运算。
安装:pip install sortedcontainers
立即学习“Python免费学习笔记(深入)”;
基础用法示例:
from sortedcontainers import SortedSet <p>a = SortedSet([3, 1, 4]) b = SortedSet([1, 5, 9])</p><p>print(a & b) # SortedSet([1]) print(a | b) # SortedSet([1, 3, 4, 5, 9]) print(a - b) # SortedSet([3, 4]) print(a ^ b) # SortedSet([3, 4, 5, 9])
注意点:
-
SortedSet自动排序,不保留插入顺序;若需插入顺序,请跳到下节 - 所有运算返回新的
SortedSet,不是就地修改 - 支持
.isdisjoint()、.issubset()等方法,行为与set一致 - 不支持
list或dict_keys直接参与运算——必须显式转成SortedSet,否则报TypeError: unsupported operand type
用 OrderedDict 或 dict(Python 3.7+)自定义插入顺序集合
若核心诉求是“按首次插入顺序去重并保持该顺序”,而不是数值排序,SortedSet 就不适用。此时可轻量封装:
class OrderedSet:
def __init__(self, iterable=None):
self._dict = dict.fromkeys(iterable) if iterable else {}
<pre class='brush:python;toolbar:false;'>def __and__(self, other):
return OrderedSet(x for x in self if x in other)
def __or__(self, other):
return OrderedSet(list(self) + list(other))
def __sub__(self, other):
return OrderedSet(x for x in self if x not in other)
def __contains__(self, x):
return x in self._dict
def __iter__(self):
return iter(self._dict)
def __len__(self):
return len(self._dict)
def __repr__(self):
return f"OrderedSet({list(self)})"</pre>使用场景与限制:
- 适用于小规模数据(
__and__是 O(n×m),无索引加速) -
__or__会拼接后去重,保留左操作数顺序,符合直觉 - 不支持
+=、-=等就地运算符,如需得额外实现update方法 - 不能直接用于
collections.abc.Set的 isinstance 检查,除非继承并注册
实际项目中,选 SortedSet 还是自定义 OrderedSet,关键看“有序”指什么:是值有序(选前者),还是插入有序(后者更合适)。两者都不该被当成 list 的替代品来频繁索引——那是设计误用。


















