bisect –維護有序列表
目的:不需要每次調用sort的方式維護有序列表。
bisect模組實作了一個演算法用於插入元素到有序列表。在某些情況下,這比反覆排序清單或建構一個大的清單再排序的效率更高。 Bisect是二分法的意思,這裡使用二分法來排序,bisect的原始碼是二分法排序的樣板。這個模組的程式碼不到100行。
插入
import bisect
import random
# Use aconstant seed to ensure that
# the # Use aconstant seed to ensure that
# the # Use aconstant seed to ensure that
random.seed(1)
print'New Pos Contents'
print'--- --- --------'
# Generaterandom numbers and
# Generaterand建立 a
l = []
for i inrange(1, 15):
r = random.randint(1, 100)
position = bisect.bisect(l,)
position = bisect.bisect(l,)
position = bisect.bisect(l,)
)print'%3d %3d' % (r, position), l執行結果:#./bisect_example.pyNew Pos Contents--- --
14 0[14]
85 1[14, 85]
77 1[14, 77, 85]
26 1[14, 26, 77, 85]
50 2[14, 26 , 50, 77, 85]
45 2[14, 26, 45, 50, 77, 85]
66 4[14, 26]
66 4[14, 26, 46,707, [14, 26, 45, 50, 66, 77, 79, 85]
10 0[10, 14, 26, 45, 50, 66, 77, 79, 85]
, 50, 3 45, 50, 66, 77, 79, 85] 84 9[3, 10, 14, 26, 45, 50, 66, 77, 79, 84, 85]1, 45 26, 44, 45, 50, 66, 77, 79, 84, 85] 77 9[3, 10, 14, 26, 44, 45, 50, 66, 7, 78,59, 787,50, 66, 7, 78,59, 787,50, 66, 7, 787,59, 787,50, 66, 7, 787,59, 787,50, 66, 7, 78783, 778,50, 66, 7, 78783, 781 0[1, 3, 10, 14, 26, 44, 45, 50, 66, 77, 77, 79, 84, 85]
583%
ect85% ,x, lo=0, hi=len(a)) :
尋找在有序列表a中插入x的index。 lo和hi用於指定清單的區間,預設是使用整個清單。如果x已經存在,在其左邊插入。傳回值為index。
bisect.bisect_right(a,x, lo=0, hi=len(a))
bisect.bisect(a, x,lo=0, hi=len(a))
這2個和bisect_left類似,但如果x已經存在,在其右邊插入。
bisect.insort_left(a,x, lo=0, hi=len(a))
在有序列表a中插入x。和a.insert(bisect.bisect_left(a,x, lo, hi), x) 的效果相同。
bisect.insort_right(a,x, lo=0, hi=len(a))
bisect.insort(a, x,lo=0, hi=len(a))
和insort_left類似,但如果x已經存在,在其右邊插入。
可以函數可以分2類,bisect*,用來找出index。 Insort*用於實際插入。預設重複時從右邊插入。實際常用的估計是insort。
標準中有個根據分數計算出評級的實例:
>>> def grade(score,breakpoints=[60, 70, 80, 90], grades='FDCBA'):
... i = bisect(breakpoints, score)
... return grades[i]
...
>>> [grade(score)for score in [33, 99, 77, 70, 89, for score in [33, 99, 77, 70, 89, 090, 1090, ]]
['F', 'A', 'C','C', 'B', 'A', 'A']
Bisect不像sort一樣支援關鍵字參數,建議如下處理:
>>> data =[('red', 5), ('blue', 1), ('yellow', 8), ('black', 0)]
>>> data.sort(key= lambdar: r[1])
>>> keys =[r[1] for r in data] #precomputed list of keys
>>> data[bisect_left(keys,0)]
>>> data[bisect_left(keys,0)]ack
>' 0)>>> data[bisect_left(keys,1)]('blue', 1)>>>>> data[bisect_left(keys,5)]('red', 5) >>> data[bisect_left(keys,8)]('yellow', 8)