Python中bisect的使用方法
Python中列表(list)的實現(xiàn)其實是一個數(shù)組,當要查找某一個元素的時候時間復(fù)雜度是O(n),使用list.index()方法,但是隨著數(shù)據(jù)量的上升,list.index()的性能也逐步下降,所以我們需要使用bisect模塊來進行二分查找,前提我們的列表是一個有序的列表。
遞歸二分查找和循環(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
為了比對一下兩者的性能,我們使用timeit模塊來測試兩個方法執(zhí)行,timeit模塊的timeit方法默認會對需要測試的函數(shù)執(zhí)行1000000,然后返回執(zhí)行的時間。
>>> 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)二分查找比遞歸二分查找性能要來的好些?,F(xiàn)在,我們先用bisect的二分查找測試一下性能
用bisect來搜索
>>> 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
對比之前,我們可以看到用bisect模塊的二分查找的性能比循環(huán)二分查找快一倍。再來對比一下,如果用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秒,相比之前的二分查找,性能簡直慢到恐怖
用bisect.insort插入新元素
排序很耗時,因此在得到一個有序序列之后,我們最好能夠保持它的有序。bisect.insort就是為這個而存在的
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]
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python數(shù)據(jù)可視化使用pyfinance分析證券收益示例詳解
這篇文章主要為大家介紹了python數(shù)據(jù)可視化使用pyfinance分析證券收益的示例詳解及pyfinance中returns模塊的應(yīng)用,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11
Python中os.path.join函數(shù)的用法示例詳解
這篇文章主要給大家介紹了關(guān)于Python中os.path.join函數(shù)用法的相關(guān)資料,os.path.join函數(shù)是Python標準庫中的一個函數(shù),用于將多個路徑組合成一個有效的路徑,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2023-10-10

