分享一下python中一个专门提供排序的库 sortedcontainers。该库提供了三个有用的类:SortedList、SortedDict、SortedSet。这里主要讲讲SortedList的操作。
官网:http://www.grantjenks.com/docs/sortedcontainers/sortedlist.html
我们可以通过以下方式声明一个SortedList对象,输出时发现里面的值已经排好序了。
from sortedcontainers import SortedList
test_sl = SortedList([3,5,1,2,7,6,4])
print(test_sl)
output: SortedList([1, 2, 3, 4, 5, 6, 7])
下面是一些常见的操作
test_sl.add(2) #添加元素
test_sl.add(8)
test_sl.add(1)
print(test_sl)
test_sl.remove(4) #删除元素 元素不存在时会报错
test_sl.discard(1) #删除元素 元素不存在时不会报错
print(test_sl)
test_sl.pop() #移除最后一个元素
print(test_sl)
pos_left = test_sl.bisect_left(2) #查找元素存在的位置
pos_right = test_sl.bisect_left(2)
print(pos_left, pos_right)
num = test_sl.count(2) #计数
print(num)
ind = test_sl.index(2) #返回第一次出现的下标
print(ind)
output:
SortedList([1, 2, 3, 4, 5, 6, 7])
SortedList([1, 1, 2, 2, 3, 4, 5, 6, 7, 8])
SortedList([1, 2, 2, 3, 5, 6, 7, 8])
SortedList([1, 2, 2, 3, 5, 6, 7])
1 1
2
1
SortedList的排序方法是系统默认的,我们也可以设置排序方法,比如数值从大到小排序
from sortedcontainers import SortedList
from operator import neg
test_sl = SortedList([3,5,1,2,7,6,4], key=neg)
print(test_sl)
output:
SortedKeyList([7, 6, 5, 4, 3, 2, 1], key=<built-in function neg>)
按字符串长度排序:
from sortedcontainers import SortedList
test_str = SortedList(["1", "431", "34"], key=lambda item:len(item))
print(test_str)
output:
SortedKeyList(['1', '34', '431'], key=<function <lambda> at 0x7fb883b36820>)
我们可以通过源码找到发现该类具体实现的方式:
def add(self, value):
"""Add `value` to sorted list.
Runtime complexity: `O(log(n))` -- approximate.
>>> sl = SortedList()
>>> sl.add(3)
>>> sl.add(1)
>>> sl.add(2)
>>> sl
SortedList([1, 2, 3])
:param value: value to add to sorted list
"""
_lists = self._lists
_maxes = self._maxes
if _maxes:
pos = bisect_right(_maxes, value)
if pos == len(_maxes):
pos -= 1
_lists[pos].append(value)
_maxes[pos] = value
else:
insort(_lists[pos], value)
self._expand(pos)
else:
_lists.append([value])
_maxes.append(value)
self._len += 1
上面是add操作的源码。该类里面维持了一个排序好的列表。在插入时,首先找到元素应该插入的位置(如果相同则插入到最右边)。insort是直接调用了bisect里的方法。