为什么添加一个`反向'参数来平分被认为效率低下的函数?

时间:2014-04-02 03:31:41

标签: python binary-search

我们可以使用Python的bisect模块有效地将项目插入已排序的列表中。

但是列表必须按升序排序,但情况并非总是如此。

documentation中,解释了原因:

  
    

与sorted()函数不同,bisect()函数具有关键或反向参数没有意义,因为这会导致设计效率低下(连续调用bisect函数不会“记住”以前的所有函数密钥查找)。

  

但是,当我查看source code时,我看不出任何似乎“记住”键查找的内容。

我们可以添加一个reversed参数,并在必要时交换此条件表达式的then部分:

if x < a[mid]: hi = mid
else: lo = mid+1

为什么这被认为是效率低下的设计?

2 个答案:

答案 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