本模組實現已經排序的隊列列表插入元素之後保持排序。對於個大量資料的列表來看,插入元素並保持排序,計算量是非常大的。本模組實現了bisect演算法,主要基於二分演算法來實現。
bisect.bisect_left(a, x, lo=0, hi=len(a))
對有序列表a裡插入元素x,保持有序不變,返回插入的位置。參數lo和hi是表示判斷列表的範圍,預設是整個範圍。如果插入的元素x已經在列表a存在,那就插入在存在元素的左邊。
例子:
#Python 3.4
import bisect
l = [8, 5, 6, 6, 3]
l.sort()
print(l)
print(bisect.bisect_left(l, 0))
print(l)
print(bisect.bisect_left(l, 5))
print(bisect.bisect_left(l, 7))
結果輸出如下:
[3, 5, 6, 6, 8]
0
[3, 5, 6, 6, 8]
1
4
bisect.bisect_right(a, x, lo=0, hi=len(a))
bisect.bisect(a, x, lo=0, hi=len(a))
在有序隊列a裡尋找x可以插入的位置,並保持隊列有序。如果插入的值與隊列裡的值相同,則插入在相同元素的右邊,把這個位置的索引值返回。
例子:
#python 3.4
import bisect
l = [8, 5, 6, 6, 3]
l.sort()
print(l)
print(bisect.bisect_right(l, 0))
print(l)
print(bisect.bisect(l, 5))
print(bisect.bisect(l, 7))
結果輸出如下:
[3, 5, 6, 6, 8]
0
[3, 5, 6, 6, 8]
2
4
bisect.insort_left(a, x, lo=0, hi=len(a))
插入一個元素x到隊列a,並把把隊列排序。要當於:a.insert(bisect.bisect_left(a, x, lo, hi), x)。
例子:
#python 3.4
import bisect
l = [8, 5, 6, 6, 3]
l.sort()
print(l)
bisect.insort_left(l, 0)
print(l)
bisect.insort_left(l, 5)
print(l)
bisect.insort_left(l, 7)
print(l)
結果輸出如下:
[3, 5, 6, 6, 8]
[0, 3, 5, 6, 6, 8]
[0, 3, 5, 5, 6, 6, 8]
[0, 3, 5, 5, 6, 6, 7, 8]
bisect.insort_right(a, x, lo=0, hi=len(a))
bisect.insort(a, x, lo=0, hi=len(a))
插入元素x到a隊列裡,如果發現有相同元素,就插入到相同元素的右邊。
例子:
#python 3.4
import bisect
l = [8, 5, 6, 6, 3]
l.sort()
print(l)
bisect.insort_right(l, 0)
print(l)
bisect.insort(l, 5)
print(l)
bisect.insort(l, 7)
print(l)
結果輸出如下:
[3, 5, 6, 6, 8]
[0, 3, 5, 6, 6, 8]
[0, 3, 5, 5, 6, 6, 8]
[0, 3, 5, 5, 6, 6, 7, 8]
使用上面的函數進行一些簡單的封裝:
def index(a, x):
'Locate the leftmost value exactly equal to x'
i = bisect_left(a, x)
if i != len(a) and a[i] == x:
return i
raise ValueError
def find_lt(a, x):
'Find rightmost value less than x'
i = bisect_left(a, x)
if i:
return a[i-1]
raise ValueError
def find_le(a, x):
'Find rightmost value less than or equal to x'
i = bisect_right(a, x)
if i:
return a[i-1]
raise ValueError
def find_gt(a, x):
'Find leftmost value greater than x'
i = bisect_right(a, x)
if i != len(a):
return a[i]
raise ValueError
def find_ge(a, x):
'Find leftmost item greater than or equal to x'
i = bisect_left(a, x)
if i != len(a):
return a[i]
raise ValueError
使用來對學產生績轉換為ABCDF等級:
#python 3.4
import bisect
def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
i = bisect.bisect(breakpoints, score)
return grades[i]
print([33, 99, 77, 70, 89, 90, 100])
print([grade(score) for score in [33, 99, 77, 70, 89, 90, 100]])
結果輸出如下:
[33, 99, 77, 70, 89, 90, 100]
['F', 'A', 'C', 'C', 'B', 'A', 'A']