查看在列表上实现插入排序的本机 bisect.insort(),这应该完全符合您的需求,因为 complexity is O(n) at best and O(n^2) at worst 而不是 O(nlogn) 与您当前的解决方案(插入后重新排序)。
但是,有更快的替代方法来构建排序的数据结构,例如Skip Lists 和二叉搜索树,它们允许插入复杂度最高为 O(log n),最坏为 O(n),甚至更好的 B -trees,Red-Black trees,Splay 树和 AVL 树,在最佳和最坏情况下都具有 O(log n) 的复杂度。有关所有这些解决方案和其他解决方案的复杂性的更多信息,请参阅 Eric Rowell 的 BigO CheatSheet。但请注意,所有这些解决方案都需要您安装第三方模块,并且通常需要使用 C 编译器进行编译。
但是,有一个名为 sortedcontainers 的纯 python 模块,它声称与 C 编译的 AVL 树和 B 树实现的 Python 扩展 (benchmark available here) 一样快或更快。
我对一些解决方案进行了基准测试,看看哪个解决方案执行插入排序最快:
sortedcontainers: 0.0860911591881
bisect: 0.665865982912
skiplist: 1.49330501066
sort_insert: 17.4167637739
这是我用来进行基准测试的代码:
from timeit import Timer
setup = """
L = list(range(10000)) + list(range(10100, 30000))
from bisect import insort
def sort_insert(L, x):
L.append(x)
L.sort()
from lib.skiplist import SkipList
L2 = SkipList(allowDups=1)
for x in L:
L2.insert(x)
from lib.sortedcontainers import SortedList
L3 = SortedList(L)
"""
# Using sortedcontainers.SortedList()
t_sortedcontainers = Timer("for i in xrange(10000, 10100): L3.add(i)", setup)
# Using bisect.insort()
t_bisect = Timer("for i in xrange(10000, 10100): insort(L, i)", setup)
# Using a Skip List
t_skiplist = Timer("for i in xrange(10000, 10100): L2.insert(i)", setup)
# Using a standard list insert and then sorting
t_sort_insert = Timer("for i in xrange(10000, 10100): sort_insert(L, i)", setup)
# Timing the results
print t_sortedcontainers.timeit(number=100)
print t_bisect.timeit(number=100)
print t_skiplist.timeit(number=100)
print t_sort_insert.timeit(number=100)
因此,结果表明 sortedcontainers 确实比 bisect 快了近 7 倍(我预计速度差距会随着列表大小而增加,因为复杂性是一个数量级的不同)。 p>
更令人惊讶的是skip list比bisect慢,但可能是因为它没有bisect优化,它是用C实现的,可能会使用一些优化技巧(注意我使用的skiplist.py模块是我能找到的最快的纯 Python 跳过列表,pyskip module 要慢很多)。
另外值得注意的是:如果您需要使用比列表更复杂的结构,sortedcontainers 模块提供了 SortedList、SortedListWithKey、SortedDict 和 SortedSet(而 bisect 仅适用于列表)。另外,您可能会对这个somewhat related benchmark 和这个complexity cheatsheet of various Python operations 感兴趣。