二分查找与 bisect 模块

博客介绍了二分查找及 Python 的 bisect 模块。通过代码示例展示了使用 bisect 模块计算元素在有序列表中应出现的位置,还根据命令行参数选择不同的 bisect 函数。此外,给出了利用 bisect 模块进行成绩分级的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

# 二分查找算法  
原理:
在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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值