Python中实现二分查找和插入的bisect模块的用法
根据官方文档,bisect中的方法包括:
bisect.bisect_left(a,x,lo=0,hi=len(a),*,key=None),在有序数组a中[lo,hi]区间内查找x插入的位置,返回的是索引值。如果a中有跟x相同的元素,则x插入的位置是左边(不理解可以看下方的例子),key指定了一个单参数的方法,该方法的返回值作为与k比较的基准(不理解看下方例子)。
值得注意的是,key参数是3.10版本以后才添加的功能。
bisect.bisect_right(a,x,lo=0,hi=len(a),*,key=None),在有序数组a中[lo,hi]区间内查找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
可见,针对上面给出的数组,想要插入2,使用bisect_left返回的索引值是1,使用bisect(bisect_right)返回的索引值是3。如果指定了lo和hi的话,那么返回的就是在这个范围内的索引。如下面的例子所示。
# 指定lo和hi
import bisect nums=[1,2,2,2,2,4] i=bisect.bisect_left(nums,2,3) print(i) # 输出为3
如果不指定lo=3的话,返回的索引应该是1。指定lo=3后,返回的索引为3。
关键字key指定了一个方法,这个方法会接受当前数组中的中间值mid(因为二分查找就是从中间值开始的)作为其参数,然后返回一个值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方法的执行顺序是这样的:
1.nums中的中间值mid=4, divide(mid)方法返回值为2
2.5>2,则查找nums的右子数组,即[6,8]
3.[6,8]的中间值是mid=8, divide(mid)方法返回值为4
4.5>4,则继续查找右子数组,可是已经没有右子数组了,则返回索引值为6.
上面代码的输出为:
bisect.insort_left(a,x,lo=0,hi=len(a),*,key=None),在有序数组a中插入x,相同的值则插在最左边。
bisect.insort_right(a,x,lo=0,hi=len(a),*,key=None),在有序数组a中插入x,相同的值则插在最右边。
bisect.insort(a,x,lo=0,hi=len(a),*,key=None),同上。
# 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指定的方法的参数是针对x的。也就是说insort_left方法的执行顺序是这样的:
1.mid=x=5,返回的值是2,也就是divide(x)
2.mid是数组的中间值,即mid=4, divide方法返回的值是2
3.divide(x)==2,则查找左子数组
4.中间值为2,mid=2, divide方法返回的值是1
5.divide(x)>1,则查找右子数组
6.中间值为3,mid=3, divide方法的返回值是1
7.divide(x)>1,则查找右子数组
8.没有右子数组了,则插入位置的索引为3
得到了插入5之后的数组为[1,2,3,5,4,6,8]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧