我们可以使用Python的bisect
模块有效地将项目插入已排序的列表中。
但是列表必须按升序排序,但情况并非总是如此。
在documentation中,解释了原因:
与sorted()函数不同,bisect()函数具有关键或反向参数没有意义,因为这会导致设计效率低下(连续调用bisect函数不会“记住”以前的所有函数密钥查找)。
但是,当我查看source code时,我看不出任何似乎“记住”键查找的内容。
我们可以添加一个reversed
参数,并在必要时交换此条件表达式的then
部分:
if x < a[mid]: hi = mid
else: lo = mid+1
为什么这被认为是效率低下的设计?
答案 0 :(得分:1)
文档说的是bisect
函数旨在在同一个项目列表上反复使用。而不是使用函数评估来动态计算密钥,预先计算密钥并使用它们更有效,特别是因为项目列表和密钥列表是并行的,因此可以使用相同的索引。
至于反转,你可以通过反转键列表获得相同的效果:
items = [9,7,5,3,1]
keys = list(reversed(items))
index = len(items)-bisect_right(keys,7)
但同样,只有在一次又一次地重复使用相同的密钥进行多次搜索时,这才有意义。
答案 1 :(得分:0)
您可以编写某种适配器:
import bisect
class rvrbisect:
def __init__(self, data):
self.data = data
def idxcnv(self, idx): return len(self.data) - idx - 1
def __getitem__(self, idx):
return self.data[self.idxcnv(idx)]
def __setitem__(self, idx, value):
self.data[self.idxcnv(idx)] = value
def __len__(self): return len(self.data)
def insert(self, idx, value):
self.data.insert(self.idxcnv(idx) + 1, value)
data = rvrbisect([30, 20, 10])
bisect.insort(data, 25)
bisect.insort(data, 15)
bisect.insort(data, 1)
bisect.insort(data, 190)
print data.data