python模組介紹- bisect模組維護有序列表

pythontab發表於2013-04-23

bisect –維護有序列表

目的:不需要每次呼叫sort的方式維護有序列表。

bisect模組實現了一個演算法用於插入元素到有序列表。在一些情況下,這比反覆排序列表或構造一個大的列表再排序的效率更高。Bisect是二分法的意思,這裡使用二分法來排序,bisect的原始碼是二分法排序的樣板。這個模組的程式碼不到100行。

插入

import bisect
import random
  
# Use aconstant seed to ensure that
# the samepseudo-random numbers
# are usedeach time the loop is run.
random.seed(1)
  
print'New  Pos Contents'
print'---  --- --------'
  
# Generaterandom numbers and
# insert theminto a list in sorted
# order.
l = []
for i inrange(1, 15):
#產生1-100的隨機數
    r = random.randint(1, 100)
    position = bisect.bisect(l, r)
    bisect.insort(l, r)
print'%3d  %3d' % (r, position), l


執行結果:

#./bisect_example.py

New  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, 45, 50, 66, 77, 85]

79    6[14, 26, 45, 50, 66, 77, 79, 85]

10    0[10, 14, 26, 45, 50, 66, 77, 79, 85]

 3    0[3, 10, 14, 26, 45, 50, 66, 77, 79, 85]

84    9[3, 10, 14, 26, 45, 50, 66, 77, 79, 84, 85]

44    4[3, 10, 14, 26, 44, 45, 50, 66, 77, 79, 84, 85]

77    9[3, 10, 14, 26, 44, 45, 50, 66, 77, 77, 79, 84, 85]

 1    0[1, 3, 10, 14, 26, 44, 45, 50, 66, 77, 77, 79, 84, 85]

Bisect模組提供的函式有:

bisect.bisect_left(a,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, 90, 100]]

['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)]
('black', 0)
>>> data[bisect_left(keys,1)]
('blue', 1)
>>> data[bisect_left(keys,5)]
('red', 5)
>>> data[bisect_left(keys,8)]
('yellow', 8)



相關文章