python_bisect模塊

一、用bisect 來管理已排序的序列

bisect 模塊包含兩個主要函數(shù),bisectinsort瓤逼,兩個函數(shù)都利用二分查找算法來在有序序列中查找或插入元素

1.1 用bisect來搜索

bisect(haystack, needle)haystack 里搜索 needle 的位置礼华,該位置滿足的條件是,把 needle 插入這個位置之后戏售,haystack 還能保持升序侨核。也就是說這個函數(shù)返回的位置前面的值草穆,都小于或等于 needle 的值。其中 haystack 必須是一個有序的序列搓译。你可以先用 bisect(haystack, needle) 查找位置 index悲柱,再用 haystack.insert(index, needle) 來插入新值。當然也可以用 insort 來一步到位些己,并且后者的速度更快一些豌鸡。

import bisect
import sys

HAYSTACK = [1, 4, 5, 6, 8, 11, 13, 15, 20, 21, 23, 23, 26, 29, 30]
NEEDLES = [0, 1, 2, 5, 8, 10, 22, 24, 25, 29, 30, 31]

ROW_FMT = '{0: 2d} @ {1: 2d}    {2}{0: < 2d}'


def demo(bisect_fn):
    for needle in reversed(NEEDLES):
        position = bisect_fn(HAYSTACK, needle)    # 用特定的bisect 函數(shù)來計算元素應該出現(xiàn)的位置
        offset = position * ' |'              # 利用該位置來算出需要幾個分隔符號
        print(ROW_FMT.format(needle, position, offset))   # 把元素和其應該出現(xiàn)的位置打印出來


if __name__ == '__main__':
    if sys.argv[-1] == 'left':        # 根據(jù)命令上最后一個參數(shù)來選用bisect 函數(shù)
        bisect_fn = bisect.bisect_left
    else:
        bisect_fn = bisect.bisect_right

    print('DEMO: ', bisect_fn.__name__)    # 把選定的函數(shù)在抬頭打印出來。
    print('haystack -> ', ' '.join('%2d' % n for n in HAYSTACK))
    demo(bisect_fn)

運行結(jié)果如下:

F:\anaconda\python.exe E:/project/demo/demo2.py
DEMO:  bisect_right
haystack ->   1  4  5  6  8 11 13 15 20 21 23 23 26 29 30
 31 @  15     | | | | | | | | | | | | | | | 31
 30 @  15     | | | | | | | | | | | | | | | 30
 29 @  14     | | | | | | | | | | | | | | 29
 25 @  12     | | | | | | | | | | | | 25
 24 @  12     | | | | | | | | | | | | 24
 22 @  10     | | | | | | | | | | 22
 10 @  5     | | | | | 10
 8 @  5     | | | | | 8
 5 @  3     | | | 5
 2 @  1     | 2
 1 @  1     | 1
 0 @  0     0

Process finished with exit code 0
bisect 的表現(xiàn)可以從兩個方面來調(diào)教

首先可以用它的兩個可選參數(shù)——lo 和 hi——來縮小搜尋的范圍段标。lo的默認值是0涯冠,hi的默認值是序列的長度,即len()作用于該序列的返回值怀樟。

其次功偿, bisect 函數(shù)其實是 bisect_right 函數(shù)的別名,后者還有個姊妹函數(shù)叫做 bisect_left往堡。它們的區(qū)別在于械荷,bisect_left 返回的插入位置是原序列中跟被插入元素相等的位置,也就是新元素會被放置于它相等的元素前面虑灰,而 bisect_right 返回的則是跟它相等的元素之后的位置吨瞎。

bisect 可以用來建立一個用數(shù)字作為索引的查詢表格,比如說把分數(shù)個成績對應起來穆咐。

import bisect
def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
    i = bisect.bisect(breakpoints, score)
    return grades[i]


student_grade = [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]

print(student_grade)

運行結(jié)果如下:

F:\anaconda\python.exe E:/project/demo/demo2.py
['F', 'A', 'C', 'C', 'B', 'A', 'A']

Process finished with exit code 0

二颤诀、用 bisect.insort 插入新元素

排序很耗時,因此在得到一個有序序列之后对湃,我們最好能保持它的有序崖叫。 bisect.insort 就是為了這個而存在的。

insort(seq, item) 把變量item插入序列 seq 中拍柒,并能保持 seq 的升序順序心傀。

import bisect
import random

SIZE = 7

random.seed(1729)

my_list = []
for i in range(SIZE):
    new_item = random.randrange(SIZE * 2)
    bisect.insort(my_list, new_item)
    print("%2d -> " % new_item, my_list)

運行結(jié)果如下:

F:\anaconda\python.exe E:/project/demo/demo2.py
10 ->  [10]
 0 ->  [0, 10]
 6 ->  [0, 6, 10]
 8 ->  [0, 6, 8, 10]
 7 ->  [0, 6, 7, 8, 10]
 2 ->  [0, 2, 6, 7, 8, 10]
10 ->  [0, 2, 6, 7, 8, 10, 10]

Process finished with exit code 0

insortbisect 一樣, 有 lohi 兩個可選參數(shù)來控制查找范圍拆讯。它也有個變體叫 insort_left , 這個變體在背后用的是 bisect_left 脂男。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市种呐,隨后出現(xiàn)的幾起案子宰翅,更是在濱河造成了極大的恐慌,老刑警劉巖爽室,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汁讼,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機嘿架,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門卜录,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人眶明,你說我怎么就攤上這事】鸶撸” “怎么了搜囱?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長柑土。 經(jīng)常有香客問我蜀肘,道長,這世上最難降的妖魔是什么稽屏? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任扮宠,我火速辦了婚禮,結(jié)果婚禮上狐榔,老公的妹妹穿的比我還像新娘坛增。我一直安慰自己,他們只是感情好薄腻,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布收捣。 她就那樣靜靜地躺著,像睡著了一般庵楷。 火紅的嫁衣襯著肌膚如雪罢艾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天尽纽,我揣著相機與錄音咐蚯,去河邊找鬼。 笑死弄贿,一個胖子當著我的面吹牛春锋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挎春,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼看疙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了直奋?” 一聲冷哼從身側(cè)響起能庆,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎脚线,沒想到半個月后搁胆,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年渠旁,在試婚紗的時候發(fā)現(xiàn)自己被綠了攀例。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡顾腊,死狀恐怖粤铭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情杂靶,我是刑警寧澤梆惯,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站吗垮,受9級特大地震影響垛吗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜烁登,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一怯屉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧饵沧,春花似錦锨络、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锁右,卻和暖如春失受,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背咏瑟。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工拂到, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人码泞。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓兄旬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親余寥。 傳聞我的和親對象是個殘疾皇子领铐,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容