web-dev-qa-db-ja.com

pythonにはソートされたリストがありますか?

つまり、次の構造を意味します。

  • O(log n)x.Push()操作の複雑さ
  • O(log n)複雑さで要素を見つける
  • ソートされるlist(x)を計算するO(n)の複雑さ

また、現在の here であるlist(...).insert(...)のパフォーマンスに関する関連する質問もありました。

116
ilya n.

標準のPythonリストはどの形式でもソートされません。標準の heapq モジュールを使用して、既存のリストにO(log n)を追加し、最小のリストを削除できますO(log n)に1つありますが、定義ではソートされたリストではありません。

Pythonの要件を満たすバランスツリーのさまざまな実装があります。たとえば、 rbtreeRBTree 、または pyavl =。

49

Big-O要件に特別な理由はありますか?それとも、ただ速くしたいですか? sortedcontainers モジュールはpure-Pythonであり、高速です(blistやrbtreeのようなfast-as-C実装のように)。

パフォーマンス比較 は、ベンチマークをより高速に、またはblistのソート済みリストタイプと同等に表示します。また、rbtree、RBTree、およびPyAVLはソートされたdictおよびsetタイプを提供しますが、ソートされたリストタイプはありません。

パフォーマンスが必要な場合は、必ずベンチマークを行ってください。 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
57
GrantJ

基本的な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リストは実際には配列です (例えば、スキップリストなどではありません)。まあ、それらは単純なものでなければなりませんが、私にとっては、名前は少し誤解を招くものです。


したがって、私が間違っていなければ、二分法/リストの速度はおそらく次のようになります。

  • push()の場合:最悪の場合はO(n);
  • 検索の場合:配列のインデックス付けの速度をO(1)と見なす場合、検索はO(log(n))操作である必要があります。
  • リスト作成の場合:O(n)はリストのコピー速度である必要があります。そうでない場合、同じリストの場合はO(1)です

pd。コメントでの議論に続いて、ここにこれらのSOの質問をリンクさせてください: Pythonのリストの実装方法 および pythonリスト関数の実行時の複雑さは何ですか

31
ジョージ
import bisect

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

(まだ)カスタム検索機能を提供していませんが、 heapq モジュールはニーズに合っているかもしれません。通常のリストを使用してヒープキューを実装します。キューの内部構造を利用する独自の効率的なメンバーシップテストを作成する必要があります(O(log n)、Iと言う...)。欠点が1つあります。ソートされたリストの抽出には複雑性O(n log n)があります。

6
Stephan202

biscectまたはsortedcontainersモジュールを使用します。私は実際には経験がありませんが、heapqモジュールは機能すると思います。 Heap Queueが含まれています

1
Slass33

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

0
Fan