python不用sort排序给输入数字排序_替代python的.sort()(用于插入大型列表并保持其排序)...

请参阅在列表上实现插入排序的原生bisect.insort(),这应该完全符合您的需求,因为

complexity is O(n) at best and O(n^2) at worst而不是O(nlogn)与您当前的解决方案(插入后求助).

但是,有更快的替代方法来构建排序数据结构,例如Skip Lists和二进制搜索树,它允许插入最多的复杂度O(log n)和最坏的O(n),或甚至更好的B树,Red-Black trees,在最佳和最差情况下都具有复杂度O(log n)的Splay树和AVL树.关于所有这些解决方案和其他解决方案的复杂性的更多信息可以在Eric Rowell的伟大BigO CheatSheet中找到.但请注意,所有这些解决方案都要求您安装第三方模块,通常需要使用C编译器进行编译.

但是,有一个名为sortedcontainers的纯python模块,它声称与AVL树和B树实现的C编译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)

因此,结果表明排序的容器确实比bisect快了近7倍(我希望速度差距随着列表大小而增加,因为复杂性是一个数量级的不同).

更令人惊讶的是跳过列表比bisect慢,但可能是因为它没有像bisect一样优化,后者在C中实现并且可能使用一些优化技巧(注意我使用的skiplist.py模块是最快的 – Python Skip List我可以发现,pyskip module慢很多).

另外值得注意的是:如果您需要使用比列表更复杂的结构,则sortedcontainers模块提供SortedList,SortedListWithKey,SortedDict和SortedSet(而bisect仅适用于列表).此外,您可能对此somewhat related benchmark和complexity cheatsheet of various Python operations感兴趣.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值