Python 新手了解二分查找bisect,看这篇就够了

1.关于左右

1.1 值存在于列表

from bisect import bisect,bisect_left,bisect_right


list_positive = [0,1,2,3,4,5]
value = 3

pos1 = bisect(list_positive,value)
pos2 = bisect_left(list_positive,value)
pos3 = bisect_right(list_positive,value)


print(f"bisect:{pos1}")#bisect:4
print(f"bisect_left:{pos2}")#bisect_left:3
print(f"bisect_right:{pos3}")#bisect_right:4

这部分很简单,当list中存在我们需要查找的值时,bisect_left会让值插在左边,而,bisect和bisect_right会插在右边。为了更加清晰看懂这个区别,我们看下面:

from bisect import bisect,bisect_left,bisect_right


list_positive = [0,1,2,3,3,3,3,3,3,3,4,5]
value = 3

pos1 = bisect(list_positive,value)
pos2 = bisect_left(list_positive,value)
pos3 = bisect_right(list_positive,value)


print(f"bisect:{pos1}")#bisect:10
print(f"bisect_left:{pos2}")#bisect_left:3
print(f"bisect_right:{pos3}")#bisect_right:10

我拉长了3,现在对左右的概念更加清晰了吧?

1.2 值不存在于列表

看代码:

from bisect import bisect,bisect_left,bisect_right


list_positive = [0,1,2,4,5]
value = 3

pos1 = bisect(list_positive,value)
pos2 = bisect_left(list_positive,value)
pos3 = bisect_right(list_positive,value)


print(f"bisect:{pos1}")#bisect:3
print(f"bisect_left:{pos2}")#bisect_left:3
print(f"bisect_right:{pos3}")#bisect_right:3

显然,刚才3变得太长了现在萎了(笑)

我们看到三个值都是3,这里能看出很bisect设计中很重要的一点:

插入位置的索引是i(此处是3),相当于原索引大于和等于i的数向右推移!

可以返回看1.1,也是这个方式。

同理,bisect.insert()也是这个原理,但是这个方法用到较少,这里不讲了

记住这点在很多插插改改的数组问题中少思考很多

2.关于有序

网上关于bisect函数使用前提大都是莫能两可的有序

什么是有序?

看代码:

from bisect import bisect,bisect_left,bisect_right


list_positive = [5,4,3,2,1,0]
value = 3

pos1 = bisect(list_positive,value)
pos2 = bisect_left(list_positive,value)
pos3 = bisect_right(list_positive,value)


print(f"bisect:{pos1}")#bisect:6
print(f"bisect_left:{pos2}")#bisect_left:6
print(f"bisect_right:{pos3}")#bisect_right:6

5,4,3,2,1,0肯定算是有序对吧?

答案很离谱对吧?

没错,我写这篇帖子要讲的就一件事:

bisect函数使用前提是正序!而不是有序!

这是官方文档:

看完知道为啥上面代码的结果是666了吧?

 3.最后

        说实话这个问题,我Herllyc本人觉得算是个问题,因为我确实被坑了,我对一个逆序数组问题二分了半天,调试了半天,才发现问题出现在bisect,只能说怪我自己不求甚解,但是看到网上几乎没有人谈及这个问题,大多数都是复制粘贴的车轱辘话,甚至GPT3.5给我的答案也很逆天(GPT3.5也认为逆序可以使用bisect),也可以看出来这个问题比较冷门了。

        本着CS领域的共享精神,我不希望关于这个问题还有更多“不求甚解”者磕磕绊绊,毕竟是一个非常简单的问题,但是属于知道了就是知道,不知道就会被坑的黑天鹅陷阱,总得来说也算是一个善意的提醒。

        当然,这种文章更多还是面向一些和我一样的小可爱,真正的大佬或许根本不需要这样的善意提醒。(#^.^#)所以大佬们就当看一只小菜B的笑话吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值