每週一個 Python 模組 | bisect

yongxinz發表於2018-12-13

專欄地址:每週一個 Python 模組

bisect 模組,用於維護有序列表。實現了一個演算法用於插入元素到有序列表。在一些情況下,這比反覆排序列表或構造一個大的列表再排序的效率更高。Bisect 是二分法的意思,這裡使用二分法來排序,它會將一個元素插入到一個有序列表的合適位置,這使得不需要每次呼叫 sort 的方式維護有序列表。

以排序順序插入

看下面的例子,insort()用於按排序順序將專案插入列表。

import bisect

# A series of random numbers
values = [14, 85, 77, 26, 50, 45, 66, 79, 10, 3, 84, 77, 1]

print('New  Pos  Contents')
print('---  ---  --------')

l = []
for i in values:
    position = bisect.bisect(l, i)
    bisect.insort(l, i)
    print('{:3}  {:3}'.format(i, position), l)
    
# output
# 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]
#  77    8 [3, 10, 14, 26, 45, 50, 66, 77, 77, 79, 84, 85]
#   1    0 [1, 3, 10, 14, 26, 45, 50, 66, 77, 77, 79, 84, 85]
複製程式碼

輸出的第一列顯示要插入的值。第二列顯示數字將插入列表的位置。第三列是當前排序列表。

處理重複

上面例子顯示的結果集包括重複值 77bisect模組提供了兩種處理重複的方法:可以將新值插入現有值的左側,也可以插入右側。insort()函式實際上是 insort_right() 的別名,它在現有值之後插入一個專案。相應的函式insort_left(),在現有值之前插入。

import bisect

# A series of random numbers
values = [14, 85, 77, 26, 50, 45, 66, 79, 10, 3, 84, 77, 1]

print('New  Pos  Contents')
print('---  ---  --------')

# Use bisect_left and insort_left.
l = []
for i in values:
    position = bisect.bisect_left(l, i)
    bisect.insort_left(l, i)
    print('{:3}  {:3}'.format(i, position), l)
    
# output
# 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]
#  77    8 [3, 10, 14, 26, 45, 50, 66, 77, 77, 79, 84, 85]
#   1    0 [1, 3, 10, 14, 26, 45, 50, 66, 77, 77, 79, 84, 85]
複製程式碼

當使用 bisect_left()insort_right() 操作相同的資料時,結果是相同的排序列表,但插入位置對於重複值是不同的。

相關文件:

pymotw.com/3/bisect/in…

www.liujiangblog.com/course/pyth…

kuanghy.github.io/2016/06/14/…

相關文章