Doc的缺少一个例子….你如何使用bisect.insort_left根据键.
试图根据键插入.
bisect.insort_left(data,('brown',7))
这将插入到数据[0].
从文档….
bisect.insort_left(list,item[,lo[,hi]]) Insert item in list in sorted order. This is equivalent to list.insert(bisect.bisect_left(list,item,lo,hi),item). This assumes that list is already sorted. >>> data = [('red',5),('blue',1),('yellow',8),('black',0)] >>> data.sort(key=lambda r: r[1]) >>> keys = [r[1] for r in data] # precomputed list of keys >>> data[bisect_left(keys,0)] ('black',0) >>> data[bisect_left(keys,1)] ('blue',1) >>> data[bisect_left(keys,5)] ('red',5) >>> data[bisect_left(keys,8)] ('yellow',8) >>>
我想在(“red”,5)之后的(‘brown’,7)放在数据中使用bisect.insort_left的排序列表中.现在,bisect.insort_left(data,(‘brown’,7))将(‘brown’,7)放在数据[0] …因为我没有使用键来插入… doc不显示使用键插入.
解决方法
这与
SortedCollection
recipe在支持关键功能的最后提到的情况基本上是一样的.
正在做的是单独的排序的密钥列表与排序的数据列表并行地保持以提高性能(它比在每个插入之前创建密钥列表更快,但是保持它并且更新它不是严格的要求). ActiveState配方在一个类中为您封装了这个,但是在下面的代码中,它们只是传递了两个独立的独立列表(因此,如果它们都被保留,它们将更容易失去同步性在食谱的一个例子中).
from bisect import bisect_left # Based on code in the SortedCollection recipe: # http://code.activestate.com/recipes/577197-sortedcollection/ def insert(seq,keys,keyfunc): """Insert an item into the sorted list using separate corresponding keys list and a keyfunc to extract key from each item. """ k = keyfunc(item) # get key i = bisect_left(keys,k) # determine where to insert item keys.insert(i,k) # insert key of item in keys list seq.insert(i,item) # insert the item itself in the corresponding spot # initialize data and keys lists data = [('red',0)] data.sort(key=lambda r: r[1]) # sort data by key value keys = [r[1] for r in data] # initialize keys list print data # --> [('black',0),('red',8)] insert(data,7),keyfunc=lambda x: x[1]) print data # --> [('black',8)]
跟进
您根本不能使用bisect.insort_left()函数来执行此操作,因为它的写入方式不支持键功能,而是将传递给它的整个项目与其中一个整数进行比较其中的数组中的项目如果[mid] x:语句.您可以在Lib/bisect.py
中查看平分模块的来源,看看我的意思.
以下是相关摘录:
def insort_left(a,x,lo=0,hi=None): """Insert item x in list a,and keep it sorted assuming a is sorted. If x is already in a,insert it to the left of the leftmost x. Optional args lo (default 0) and hi (default len(a)) bound the slice of a to be searched. """ if lo < 0: raise ValueError('lo must be non-negative') if hi is None: hi = len(a) while lo < hi: mid = (lo+hi)//2 if a[mid] < x: lo = mid+1 else: hi = mid a.insert(lo,x)
你可以修改上面的一个key-function参数并使用它:
def my_insort_left(a,hi=None,keyfunc=lambda v: v): x_key = keyfunc(x) . . . if keyfunc(a[mid]) < x_key: lo = mid+1 . . .
…并称之为:
my_insort_left(data,key=lambda v: v[1])
实际上,如果要编写一个自定义函数,为了更高的效率而牺牲一般性不需要的话,你可以省去一个通用的关键函数参数的添加,并且只需要硬编码的东西来操作所需的方式您使用的数据格式:
def my_insort_left(a,hi=None): x_key = x[1] # key on second element of each item sequence . . . if a[mid][1] < x_key: lo = mid+1 . . .
这样称呼:
my_insort_left(data,7))