二分
二分前提是有序,否则不可以二分
二分查找算法的是时间复杂度O(log n)
bisect模块
- bisect 模块提供的函数
bisect.bisect_left(a,x, lo=0, hi=len(a))
查找再有序列表a中插入x的index。lo和hi用于指定列表的区间,默认是使整个列表。如果x已经存在,在其左边插入。返回值为indexbisect.bisect_right(a,x, lo=0, hi=len(a))或bisect.bisect(a,x, lo=0, hi=len(a))
和bisect_left类似,但如果x已经存在,在其右边插入bisect.insort_left(a,x, lo=0, hi=len(a))
在有序列表a中插入x。等同于a.insert(bisect.bisect_left(a,x,lo,hi), x)bisect.insort_right(a,x, lo=0, hi=len(a))或者bisect.insort(a,x, lo=0, hi=len(a))
和insort_left函数类似,但如果已经存在,在其右边插入
- 函数可以分2类:
bisect系,用于查找index
insort系,用于实际插入
默认重复时从右边插入
import bisect
lst = [37, 88, 20, 50, 30, 65, 41, 50]
newlst = sorted(lst) # 升序
print(newlst) # [20, 30, 37, 41, 50, 50, 65, 88]
print(list(enumerate(newlst)))
# [(0, 20), (1, 30), (2, 37), (3, 41), (4, 50), (5, 50), (6, 65), (7, 88)]
print(bisect.bisect(newlst, 20)) # 1
print(bisect.bisect(newlst, 30)) # 2
print(bisect.bisect(newlst, 40)) # 3
print(bisect.bisect_left(newlst, 20)) # 0
print(bisect.bisect_left(newlst, 30)) # 1
print(bisect.bisect_left(newlst, 40)) # 3
for x in (20, 30, 40, 100):
bisect.insort_left(newlst, x)
print(newlst)
# print(newlst) 打印结果
[20, 20, 30, 37, 41, 50, 50, 65, 88]
[20, 20, 30, 30, 37, 41, 50, 50, 65, 88]
[20, 20, 30, 30, 37, 40, 41, 50, 50, 65, 88]
[20, 20, 30, 30, 37, 40, 41, 50, 50, 65, 88, 100]
应用
判断学生成绩,成绩等级A-E。其中,90分以上为’A‘,80-89分为’B‘,70-79分为’C’,60-69分为’D’,60分以下为’E‘
import bisect
def get_grade(score):
breakpoints = [60, 70, 80, 90]
grades = 'EDCBA'
return grades[bisect.bisect(breakpoints, score)]
for x in (91, 82, 77, 65, 50, 60, 70, 80, 90):
print('{} => {}'.format(x, get_grade(x)))
执行结果
91 => A
82 => B
77 => C
65 => D
50 => E
60 => D
70 => C
80 => B
90 => A
二分查找及bisect模块应用
博客介绍了二分查找,其前提是有序,时间复杂度为O(log n)。还讲解了Python的bisect模块,该模块提供查找插入位置和实际插入的函数,可分为bisect系和insort系。最后给出了用二分判断学生成绩等级的应用示例。
82

被折叠的 条评论
为什么被折叠?



