python有排序列表吗?

时间:2009-07-10 14:18:01

标签: python list sorting

我指的是一个结构:

  • x.push()操作的O(log n)复杂度
  • O(log n)查找元素的复杂性
  • O(n)计算list(x)的复杂性将被排序

我还有一个关于list(...).insert(...)的效果的相关问题,现在是here

8 个答案:

答案 0 :(得分:57)

您的大O要求是否有特殊原因?或者你只是希望它快? sortedcontainers模块是纯Python和快速的(就像blist和rbtree这样的快速实现)。

performance comparison显示基准测试的速度更快或与blist的排序列表类型相同。另请注意,rbtree,RBTree和PyAVL提供了已排序的字典和集合类型,但没有排序列表类型。

如果要求表现,请务必记住基准。在证明基准比较之前,应该怀疑一个证明Big-O符号快速声明的模块。

免责声明:我是Python sortedcontainers模块的作者。


安装:

pip install sortedcontainers

用法:

>>> from sortedcontainers import SortedList
>>> l = SortedList()
>>> l.update([0, 4, 1, 3, 2])
>>> l.index(3)
3
>>> l.add(5)
>>> l[-1]
5

答案 1 :(得分:47)

标准Python列表未以任何形式排序。标准heapq模块可用于将O(log n)附加到现有列表中,并删除O(log n)中的最小模块,但不是定义中的排序列表。

Python的平衡树有多种实现方式可以满足您的要求,例如: rbtreeRBTreepyavl

答案 2 :(得分:31)

虽然我还没有检查过基本Python列表操作的“大O”速度, 在这种情况下,bisect标准模块也值得一提:

import bisect
L = [0, 100]

bisect.insort(L, 50)
bisect.insort(L, 20)
bisect.insort(L, 21)

print L
## [0, 20, 21, 50, 100]

i = bisect.bisect(L, 20)
print L[i-1], L[i]
## 20, 21

PS。啊,抱歉,引用的问题中提到了bisect。不过,我认为如果这些信息会在这里,那将不会有多大伤害。

PPS。和CPython lists are actually arrays(不是说,跳过列表等)。嗯,我想他们必须是简单的东西,但就我而言,这个名字有点误导。


所以,如果我没有弄错的话,bisect / list的速度可能是:

  • 表示push():O(n)表示最坏的情况;
  • 进行搜索:如果我们认为数组索引的速度为O(1),则搜索应该是O(log(n))操作;
  • 用于列表创建:O(n)应该是列表复制的速度,否则它是相同列表的O(1))

更新。在评论中进行讨论后,让我在这里链接这些问题:How is Python's List ImplementedWhat is the runtime complexity of python list functions

答案 3 :(得分:6)

虽然它(尚未)提供自定义搜索功能,但heapq模块可能符合您的需求。它使用常规列表实现堆队列。您必须编写自己的有效成员资格测试,该测试利用队列的内部结构(可以在 O(log n)中完成,我会说...)。有一个缺点:提取排序列表的复杂性为 O(n log n)

答案 4 :(得分:6)

import bisect

class sortedlist(list):
    '''just a list but with an insort (insert into sorted position)'''
    def insort(self, x):
        bisect.insort(self, x)

答案 5 :(得分:1)

我会使用sortedcontainersheapq模块。我真的没有经验,但我认为Heap Queue模块有效。它包含protected void RegisterUser_CreatingUser(object sender, LoginCancelEventArgs e){ RegisterUser.Email = RegisterUser.UserName; }

答案 6 :(得分:0)

在Python上实现自己的排序列表可能并不困难。以下是概念证明:

import bisect

class sortlist:
    def __init__(self, list):
        self.list = list
        self.sort()
    def sort(self):
        l = []
        for i in range(len(self.list)):
            bisect.insort(l, self.list[i])
        self.list = l
        self.len = i
    def insert(self, value):
        bisect.insort(self.list, value)
        self.len += 1
    def show(self):
        print self.list
    def search(self,value):
        left = bisect.bisect_left(self.list, value)
        if abs(self.list[min([left,self.len-1])] - value) >= abs(self.list[left-1] - value):
            return self.list[left-1]
        else:
            return self.list[left]

list = [101, 3, 10, 14, 23, 86, 44, 45, 45, 50, 66, 95, 17, 77, 79, 84, 85, 91, 73]
slist = sortlist(list)
slist.show()
slist.insert(99)
slist.show()
print slist.search(100000000)
print slist.search(0)
print slist.search(56.7)

=========结果============

[3,10,14,17,23,44,45,45,50,66,73,77,79,84,85,86,91,95,101]

[3,10,14,17,23,44,45,45,50,66,73,77,79,84,85,86,91,95,99,101]

101

3

50

答案 7 :(得分:0)

一个 AVL 树 [https://en.wikipedia.org/wiki/AVL_tree] 加上中序遍历将在所需的时间复杂度内解决这个问题。