回答:
標準のPythonリストは、どのような形式でもソートされていません。標準のheapqモジュールを使用して、O(log n)を既存のリストに追加し、O(log n)の最小のものを削除できますが、定義ではソートされたリストではありません。
例えば、あなたの要件を満たすためのPythonのためのバランスの木の様々な実装がありrbtree、RBTree、またはpyavlが。
big-O要件に特別な理由はありますか?それとも高速にしたいですか?sortedcontainersのモジュールは、純粋なPythonと高速(blistとrbtreeなど高速AS-Cの実装のように)です。
性能比較、それが速いかblistのソートされたリストのタイプと同等のベンチマークを示しています。rbtree、RBTree、およびPyAVLはソートされたdictおよびセットタイプを提供しますが、ソートされたリストタイプがないことにも注意してください。
パフォーマンスが要件である場合は、必ずベンチマークを行うことを忘れないでください。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
0.0845024989976
ました。SortedList.add()0.596589182518
とbisect.insort()を比較したため、速度が7倍になりました。また、sortedcontainers挿入ソートはO(log n)で動作し、bisect.insort()はO(n)で動作するため、リストの長さとともに速度ギャップが大きくなると予想しています。
O(n)
基本的な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リストは実際には配列です(たとえば、スキップリストなどではありません)。まあ、それは単純なものでなければならないと思いますが、私にとっては、名前は少し誤解を招くものです。
したがって、私が間違っていない場合、二分/リスト速度はおそらく次のようになります。
更新。コメント欄での議論の後、私はここではこれらのSOの質問にリンクしてみましょう:どのようにPythonのリストが実装されているとPythonのリスト機能の実行時の複雑さとは何ですか
(まだ)カスタム検索機能を提供していませんが、heapq
モジュールはあなたのニーズに合うかもしれません。通常のリストを使用してヒープキューを実装します。キューの内部構造を使用する独自の効率的なメンバーシップテストを作成する必要があります(O(log n)で実行できます)。欠点が1つあります。ソートされたリストの抽出には複雑さO(n log n)があります。
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
memcpy
まだO(n)操作です。Pythonがリストをどのように正確に実装するかはわかりませんが、リストが連続したメモリに(確かにリンクリストとしてではなく)保存されているのではないかと思います。それが本当にそうである場合、bisect
あなたがデモンストレーションを使用する挿入は複雑さO(n)を持ちます。