Python SortedContainers 库详解:高效有序容器实现
概述
Python SortedContainers 是一个纯 Python 实现的高性能有序容器库,提供了 SortedList、SortedDict 和 SortedSet 三种主要数据结构。这些数据结构在保持元素有序的同时,提供了高效的插入、删除和查找操作,其性能可与基于 C 扩展的实现相媲美。
安装指南
安装 SortedContainers 非常简单,推荐使用 pip 工具:
python3 -m pip install sortedcontainers
对于使用 pipenv 的用户:
pipenv install sortedcontainers
安装完成后,即可在 Python 代码中导入并使用:
from sortedcontainers import SortedList, SortedDict, SortedSet
SortedList 详解
基本特性
SortedList 是一个保持元素有序的可变序列,具有以下特点:
- 自动维护元素升序排列
- 支持重复元素
- 提供快速随机访问
- 时间复杂度:插入和删除操作为 O(log n),查找操作为 O(1)
基本操作
from sortedcontainers import SortedList
# 创建空列表
sl = SortedList()
# 添加元素
sl.update([5, 1, 3, 4, 2]) # 批量添加
sl.add(0) # 单个添加
print(sl) # 输出: SortedList([0, 1, 2, 3, 4, 5])
删除操作
sl.remove(0) # 按值删除,值不存在会抛出 ValueError
sl.discard(1) # 按值删除,值不存在不会报错
sl.pop() # 删除并返回最后一个元素
del sl[1] # 按索引删除
sl.clear() # 清空列表
查找操作
sl = SortedList('abbcccddddeeeee')
# 成员检查
print('f' in sl) # False
# 计数
print(sl.count('e')) # 5
# 查找索引
print(sl.index('c')) # 3
# 二分查找
print(sl.bisect_left('d')) # 6
print(sl.bisect_right('d')) # 10
# 切片操作
print(sl[6:10]) # ['d', 'd', 'd', 'd']
迭代操作
sl = SortedList('acegi')
# 正向迭代
print(list(iter(sl))) # ['a', 'c', 'e', 'g', 'i']
# 反向迭代
print(list(reversed(sl))) # ['i', 'g', 'e', 'c', 'a']
# 范围迭代
print(list(sl.irange('b', 'h'))) # ['c', 'e', 'g']
# 索引迭代
print(list(sl.islice(1, 4))) # ['c', 'e', 'g']
SortedKeyList 详解
SortedKeyList 是 SortedList 的变体,允许通过 key 函数自定义排序规则。
from operator import neg
from sortedcontainers import SortedKeyList
# 使用 key 函数创建
skl = SortedKeyList(key=neg) # 使用负值排序
skl.update([1, 2, 3, 4, 5])
print(skl) # SortedKeyList([5, 4, 3, 2, 1], key=<built-in function neg>)
# 也可以从 SortedList 创建
values = SortedList([1, 2, 3, 4, 5], key=neg)
特殊方法
# 基于 key 的二分查找
print(skl.bisect_key_left(-4.5)) # 1
print(skl.bisect_key_right(-1.5)) # 4
# 基于 key 的范围迭代
print(list(skl.irange_key(-4.5, -1.5))) # [4, 3, 2]
使用注意事项
使用 SortedContainers 时需要注意以下三点:
- 全序关系:比较值或键必须具有全序关系
- 不可变性:比较值或键在存储在容器中时不能改变
- 键一致性:如果使用 key 函数,相等的值必须具有相等的键
常见错误示例
class Record:
def __init__(self, name, rank):
self.name = name
self.rank = rank
def __eq__(self, other):
return self.name == other.name
# 错误用法:相等的值具有不同的键
alice1 = Record('alice', 1)
bob2 = Record('bob', 2)
carol3 = Record('carol', 3)
sl = SortedList([alice1, bob2, carol3], key=lambda r: r.rank)
bob4 = Record('bob', 4)
print(bob2 == bob4) # True
print(bob4 in sl) # False,这是错误的
正确实现方式
class Record:
def __init__(self, name, rank):
self.name = name
self.rank = rank
def _cmp_key(self):
return (self.rank, self.name)
def __eq__(self, other):
return self._cmp_key() == other._cmp_key()
def __lt__(self, other):
return self._cmp_key() < other._cmp_key()
性能特点
SortedContainers 通过以下技术实现高性能:
- 使用多级列表结构(类似跳表)
- 纯 Python 实现,无需 C 扩展
- 优化的算法实现
- 内存效率高
其性能与基于 C 扩展的实现相当,在某些场景下甚至更优。
总结
Python SortedContainers 提供了一组高效、易用的有序容器类型,适合需要维护有序数据的各种场景。通过合理使用 SortedList、SortedDict 和 SortedSet,可以简化代码并提高性能。使用时需要注意全序关系和键一致性的要求,避免常见错误。
对于需要自定义排序规则的场景,SortedKeyList 提供了灵活的解决方案。该库是纯 Python 实现,具有良好的可移植性和兼容性,是处理有序数据结构的理想选择。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



