二分查找与 bisect 模块

# 二分查找算法  
原理:
在haystack(必须有序)中查找needle的位置
该位置满足的条件是:
把needle插入到这个位置之后,haystack还能保持升序
也就是在这个函数返回的位置前面的值,都小于或等于needle的值。

你可以先用bisect(haystack,needle) 查找位置index,
在用haystack.insert(index,needle)来插入新值。
但也可以用insort来一步到位,并且速度更快

import bisect
import sys

HAYSTACK = [1,4,5,6,8,12,15,20,21,23,23,26,29,30]
NEEDLES = [0,1,2,5,8,10,22,23,29,30,31]

ROW_FMT = '{0:2d} @ {1:2d}    {2}{0:<2d}'

def demo(bisect_fn):
    for needle in reversed(NEEDLES): position = bisect_fn(HAYSTACK,needle) # 计算元素应该出现的位置 # print(needle,position) offset = position * ' |' # 利用位置来算出需要几个分隔符号 print(ROW_FMT.format(needle,position,offset)) # 打印元素和应该出现的位置 if __name__ == '__main__': # print(sys.argv[-1]) if sys.argv[-1] == 'left': # 根据命令上最后一个参数来选用bisect函数 bisect_fn = bisect.bisect_left else: bisect_fn = bisect.bisect print('DEMO:',bisect_fn.__name__) # 打印选中的函数 print('haystack ->',' '.join('%2d'% n for n in HAYSTACK)) demo(bisect_fn)

结果:

DEMO: bisect_right
haystack ->  1  4  5  6  8 12 15 20 21 23 23 26 29 30
31 @ 14      |  |  |  |  |  |  |  |  |  |  |  |  |  |31
30 @ 14      |  |  |  |  |  |  |  |  |  |  |  |  |  |30
29 @ 13      |  |  |  |  |  |  |  |  |  |  |  |  |29
23 @ 11      |  |  |  |  |  |  |  |  |  |  |23
22 @  9      |  |  |  |  |  |  |  |  |22
10 @  5      |  |  |  |  |10
 8 @  5      |  |  |  |  |8 
 5 @  3      |  |  |5 
 2 @  1      |2 
 1 @  1      |1 
 0 @  0    0 

 

bisect :
可选参数:
lo默认值为0 hi默认值为序列长度,len()作用于该序列的返回值

bisect 函数其实是bisect.bisect_right函数的别名,


bisect.bisect_right() 与 bisect.bisect_left() 区别:
插入位置是原序列中跟被插入元素相等的元素的位置的时候:
bisect.bisect_left: 新元素会被放置于相等元素的前面
bisect.bisect_right: 新元素会被放置于相等元素的后面

这个细微的差别可能对于整数序列来说没什么区别,
但是对于那些值相等,但是形式不同的数据类型来说,结果就不一样了
例如 1 == 1.0 但是 1 和 1.0 其实是两个不同的元素

 

# 借助bisect可以用来建立一个用数字作为索引的查询表格
import bisect
def grade(score,breakpoints=[60,70,80,90],grades='FDCBA'):
    i = bisect.bisect(breakpoints,score)
    return grades[i]

print([grade(score) for score in [33,99,77,70,89,90,100]])

 


# 可以在很长的有序序列中作为index的替代,用来更快的查找一个元素的位置

 

转载于:https://www.cnblogs.com/LYliangying/p/9552232.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值