網(wǎng)站首頁 編程語言 正文
1.bisect模塊概述
bisect是python的內(nèi)置模塊, 用于有序序列的插入和查找。 插入的數(shù)據(jù)不會影響列表的排序, 但是原有列表需要是有序的, 并且不能是倒序.
Bisect模塊提供的函數(shù)有:
- bisect.bisect_left(a,x, lo=0, hi=len(a))
- bisect.bisect_right(a,x, lo=0, hi=len(a))
- bisect.bisect(a, x,lo=0, hi=len(a))
- bisect.insort_left(a,x, lo=0, hi=len(a))
- bisect.insort_right(a,x, lo=0, hi=len(a))
- bisect.insort(a, x,lo=0, hi=len(a))
2.bisect模塊的函數(shù)詳解
2.1 bisect.bisect*()方法
- bisect.bisect_left(a,x,lo=0,hi=len(a),*,key=None)
在有序數(shù)組a中[lo,hi]區(qū)間內(nèi)查找x插入的位置,返回的是索引值。如果a中有跟x相同的元素,則x插入的位置是左邊,key指定了一個單參數(shù)的方法,該方法的返回值作為與k比較的基準(zhǔn)。
值得注意的是,key參數(shù)是3.10版本以后才添加的功能
- bisect.bisect_right(a,x,lo=0,hi=len(a),*,key=None),在有序數(shù)組a中[lo,hi]區(qū)間內(nèi)查找x插入的位置,返回索引值。如果a中有跟x相同的元素,則x插入的位置是右邊。
- bisect.bisect(a,x,lo=0,hi=len(a),*,key=None),同bisect_right
# bisect_left Vs. bisect (bisect_right) import bisect nums = [1, 2, 2, 4] i, j = bisect.bisect_left(nums, 2), bisect.bisect(nums, 2) print(i) # 輸出1 print(j) # 輸出3
可見,針對上面給出的數(shù)組,想要插入2,使用bisect_left返回的索引值是1,使用bisect(bisect_right)返回的索引值是3。如果指定了lo和hi的話,那么返回的就是在這個范圍內(nèi)的索引。如下面的例子所示。
# 指定lo和hi import bisect nums = [1, 2, 2, 2, 2, 4] i = bisect.bisect_left(nums, 2, 3) print(i) # 輸出為3
如果不指定lo=3的話,返回的索引應(yīng)該是1。指定lo=3后,返回的索引為3。
關(guān)鍵字key指定了一個方法,這個方法會接受當(dāng)前數(shù)組中的中間值mid(因為二分查找就是從中間值開始的)作為其參數(shù),然后返回一個值val,val用于跟x比較。
# 指定key值 import bisect nums = [1, 2, 3, 4, 6, 8] def divide(mid): print('mid: ' + str(mid)) return mid // 2 i = bisect.bisect_left(nums, 5, key=divide) print(i)
上面的例子中定義了一個divide方法。那么bisect_left方法的執(zhí)行順序是這樣的:
- nums中的中間值mid=4, divide(mid)方法返回值為2
- 5>2,則查找nums的右子數(shù)組,即[6,8]
- [6,8]的中間值是mid=8, divide(mid)方法返回值為4
- 5>4,則繼續(xù)查找右子數(shù)組,可是已經(jīng)沒有右子數(shù)組了,則返回索引值為6.
2.2 bisect.insort*()方法
- bisect.insort_left(a,x,lo=0,hi=len(a),*,key=None),在有序數(shù)組a中[lo,hi]區(qū)間內(nèi)查找x插入的位置,返回的是索引值。如果a中有跟x相同的元素,則x插入的位置是最左邊,key指定了一個單參數(shù)的方法,該方法的返回值作為與k比較的基準(zhǔn)。
- bisect.insort_right(a,x,lo=0,hi=len(a),*,key=None),在有序數(shù)組a中[lo,hi]區(qū)間內(nèi)查找x插入的位置,返回索引值。如果a中有跟x相同的元素,則x插入的位置是最右邊。
- bisect.insort(a,x,lo=0,hi=len(a),*,key=None),同insort_right。
# bisect.insort_left import bisect nums = [1, 2, 3, 4, 6, 8] bisect.insort_left(nums, 5) print(nums) # [1, 2, 3, 4, 5, 6, 8]
值得注意的是,insort方法中的key和bisect方法中的key指定的方法針對的對象是不同的。
# bisect.insort_left with key import bisect nums = [1, 2, 3, 4, 6, 8] def divide(mid): print('mid: ' + str(mid)) return mid // 2 bisect.insort_left(nums, 5, key=divide)
可見,key指定的方法的參數(shù)是針對x的。也就是說insort_left方法的執(zhí)行順序是這樣的:
- mid=x=5,返回的值是2,也就是divide(x)
- mid是數(shù)組的中間值,即mid=4, divide方法返回的值是2
- divide(x)==2,則查找左子數(shù)組
- 中間值為2,mid=2, divide方法返回的值是1
- divide(x)>1,則查找右子數(shù)組
- 中間值為3,mid=3, divide方法的返回值是1
- divide(x)>1,則查找右子數(shù)組
- 沒有右子數(shù)組了,則插入位置的索引為3,得到了插入5之后的數(shù)組為[1,2,3,5,4,6,8]
3.python中的二分查找
3.1 標(biāo)準(zhǔn)的二分查找
class BinarySearch: # 標(biāo)準(zhǔn)的二分查找,找不到返回-1 def binsearch(self, nums, target): lo, hi = 0, len(nums) - 1 while lo <= hi: mid = lo + (hi - lo) // 2 if nums[mid] == target: return mid elif nums[mid] > target: hi = mid - 1 else: # nums[mid] < target: lo = mid + 1 return -1
3.2 查找第一個>=target的元素索引
class BinarySearch: # 查找第一個>=target的元素索引,找不到返回數(shù)組長度 def lowerbound(self, nums, target): lo, hi = 0, len(nums) - 1 pos = len(nums) # 找不到 while lo < hi: mid = lo + (hi - lo) // 2 if nums[mid] >= target: hi = mid else: # nums[mid] < target: lo = mid + 1 if nums[lo] >= target: # lo:要找的元素索引 pos = lo return pos
3.3 查找第一個>target的元素索引
class BinarySearch: # 查找第一個>target的元素索引,找不到返回數(shù)組長度 def upperbound(self, nums, target): lo, hi = 0, len(nums) - 1 pos = len(nums) # 找不到 while lo < hi: mid = lo + (hi - lo) // 2 if nums[mid] > target: hi = mid else: # nums[mid] <= target: lo = mid + 1 if nums[lo] > target: # lo:要找的元素索引 pos = lo return pos
4.二分查找的變形與 bisect 模塊的關(guān)系
- 二分查找中的
lowerbound(nums, target)
等價于bisect.bisect_left(a,x, lo=0, hi=len(a))
- 二分查找中的
upperbound(nums, target)
等價于bisect.bisect_right(a,x, lo=0, hi=len(a))
或者bisect.bisect(a,x, lo=0, hi=len(a))
原文鏈接:https://blog.csdn.net/weixin_44852067/article/details/126815828
相關(guān)推薦
- 2022-08-02 Android開發(fā)自定義雙向SeekBar拖動條控件_Android
- 2022-06-07 FreeRTOS實時操作系統(tǒng)臨界段保護(hù)場合示例_操作系統(tǒng)
- 2022-10-08 ASP.NET?MVC在基控制器中處理Session_實用技巧
- 2022-05-17 ubuntu下安裝go語言SDK
- 2022-12-30 React淺析Fragments使用方法_React
- 2023-06-02 python實現(xiàn)斷點調(diào)試的方法_python
- 2023-01-12 關(guān)于scipy.optimize函數(shù)使用及說明_python
- 2023-01-12 python如何批量讀取.mat文件并保存成.npy_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支