首頁  >  文章  >  後端開發  >  bisect模組維護有序列表

bisect模組維護有序列表

高洛峰
高洛峰原創
2016-10-20 09:38:281107瀏覽

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 1

14, 85]

77    1[14, 77, 85]

26    1[14, 26, 77, 85]

50    2[14, 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,757,75, 57,75, 26095, 57,757, 57,757, 57,75, 57,757, 57,757, 57,757, 57,757, 57,753, 57,75, 57,753, 57,75, 57,753, 57,75, 57,75, 57,757, 57,757, 57,575] 84    9[3, 10, 14, 26, 45, 50, 66, 77, 79, 84, 85]

44    4[3, 10, 14, 26, 45, 4   4[3, 10, 14, 26, 49, 4 84, 85]

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

 14, 3 44, 45, 50, 66, 77, 77, 79, 84, 85]

Bisect模組所提供的函數有:

bisect.bisect_left(a,x, loft(a,x, lo, bis) ) :

尋找在有序列表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, 8900],

['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)

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn