Python中bisect的使用方法
Python中列表(list)的實(shí)現(xiàn)其實(shí)是一個(gè)數(shù)組,當(dāng)要查找某一個(gè)元素的時(shí)候時(shí)間復(fù)雜度是O(n),使用list.index()方法,但是隨著數(shù)據(jù)量的上升,list.index()的性能也逐步下降,所以我們需要使用bisect模塊來(lái)進(jìn)行二分查找,前提我們的列表是一個(gè)有序的列表。
遞歸二分查找和循環(huán)二分查找
def binary_search_recursion(lst, val, start, end): if start > end: return None mid = (start + end) // 2 if lst[mid] < val: return binary_search_recursion(lst, val, mid + 1, end) if lst[mid] > val: return binary_search_recursion(lst, val, start, mid - 1) return mid def binary_search_loop(lst, val): start, end = 0, len(lst) - 1 while start <= end: mid = (start + end) // 2 if lst[mid] < val: start = mid + 1 elif lst[mid] > val: end = mid - 1 else: return mid return None
為了比對(duì)一下兩者的性能,我們使用timeit模塊來(lái)測(cè)試兩個(gè)方法執(zhí)行,timeit模塊的timeit方法默認(rèn)會(huì)對(duì)需要測(cè)試的函數(shù)執(zhí)行1000000,然后返回執(zhí)行的時(shí)間。
>>> import random >>> from random import randint >>> from random import choice >>> random.seed(5) >>> lst = [randint(1, 100) for _ in range(500000)] >>> lst.sort() >>> val = choice(lst) >>> val 6 >>> def test_recursion(): ... return binary_search_recursion(lst, val, 0, len(lst) - 1) ... >>> def test_loop(): ... return binary_search_loop(lst, val) ... >>> import timeit >>> t1 = timeit.timeit("test_recursion()", setup="from __main__ import test_recursion") >>> t1 3.9838006450511045 >>> t2 = timeit.timeit("test_loop()", setup="from __main__ import test_loop") >>> t2 2.749765167240339
可以看到,循環(huán)二分查找比遞歸二分查找性能要來(lái)的好些?,F(xiàn)在,我們先用bisect的二分查找測(cè)試一下性能
用bisect來(lái)搜索
>>> import bisect >>> def binary_search_bisect(lst, val): ... i = bisect.bisect(lst, val) ... if i != len(lst) and lst[i] == val: ... return i ... return None ... >>> def test_bisect(): ... return binary_search_bisect(lst, val) ... >>> t3 = timeit.timeit("test_bisect()", setup="from __main__ import test_bisect") >>> t3 1.3453236258177412
對(duì)比之前,我們可以看到用bisect模塊的二分查找的性能比循環(huán)二分查找快一倍。再來(lái)對(duì)比一下,如果用Python原生的list.index()的性能
>>> def test_index(): ... return lst.index(val) ... >>> t4 = timeit.timeit("test_index()", setup="from __main__ import test_index") >>> t4 518.1656223725007
可以看到,如果用Python原生的list.index()執(zhí)行1000000,需要500秒,相比之前的二分查找,性能簡(jiǎn)直慢到恐怖
用bisect.insort插入新元素
排序很耗時(shí),因此在得到一個(gè)有序序列之后,我們最好能夠保持它的有序。bisect.insort就是為這個(gè)而存在的
insort(seq, item)把變量item插入到序列seq中,并能保持seq的升序順序
import random from random import randint import bisect lst = [] SIZE = 10 random.seed(5) for _ in range(SIZE): item = randint(1, SIZE) bisect.insort(lst, item) print('%2d ->' % item, lst)
輸出:
10 -> [10]
5 -> [5, 10]
6 -> [5, 6, 10]
9 -> [5, 6, 9, 10]
1 -> [1, 5, 6, 9, 10]
8 -> [1, 5, 6, 8, 9, 10]
4 -> [1, 4, 5, 6, 8, 9, 10]
1 -> [1, 1, 4, 5, 6, 8, 9, 10]
3 -> [1, 1, 3, 4, 5, 6, 8, 9, 10]
2 -> [1, 1, 2, 3, 4, 5, 6, 8, 9, 10]
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python讀寫Excel表格的實(shí)例代碼(簡(jiǎn)單實(shí)用)
這篇文章主要介紹了python讀寫Excel表格的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12在Django中動(dòng)態(tài)地過(guò)濾查詢集的實(shí)現(xiàn)
本文主要介紹了Django中動(dòng)態(tài)地過(guò)濾查詢集的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03使用Python對(duì)MySQL數(shù)據(jù)操作
本文介紹Python3使用PyMySQL連接數(shù)據(jù)庫(kù),并實(shí)現(xiàn)簡(jiǎn)單的增刪改查。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-04-04python爬蟲(chóng)搭配起B(yǎng)ilibili唧唧的流程分析
這篇文章主要介紹了python爬蟲(chóng)搭配起B(yǎng)ilibili唧唧的流程分析,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12python根據(jù)出生年份簡(jiǎn)單計(jì)算生肖的方法
這篇文章主要介紹了python根據(jù)出生年份簡(jiǎn)單計(jì)算生肖的方法,通過(guò)一個(gè)非常簡(jiǎn)單的自定義函數(shù)實(shí)現(xiàn)輸入年份得到生肖的功能,非常實(shí)用,需要的朋友可以參考下2015-03-03Python入門學(xué)習(xí)之字符串與比較運(yùn)算符
這篇文章主要介紹了Python入門學(xué)習(xí)之字符串與比較運(yùn)算符,是Python語(yǔ)法中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-10-10詳解使用PyInstaller將Pygame庫(kù)編寫的小游戲程序打包為exe文件
這篇文章主要介紹了詳解使用PyInstaller將Pygame庫(kù)編寫的小游戲程序打包為exe文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08