bisect 二分查找

 先说明的是,使用这个模块的函数前先确保操作的列表是已排序的。

      

       先看看 insort  函数:

       

       其插入的结果是不会影响原有的排序。

       再看看 bisect  函数:

       

       其目的在于查找该数值将会插入的位置并返回,而不会插入。

       接着看 bisect_left 和 bisect_right 函数,该函数用入处理将会插入重复数值的情况,返回将会插入的位置

 

Python 著名的数据处理库 numpy 也有一个用于二分查找的函数 numpy.searchsorted, 用法与 bisect 基本相同,只不过如果要右边插入时,需要设置参数 side='right',例如:

 searchsorted 不适合用于搜索普通的数组,但是它用来搜索 numpy.ndarray 是相当快的:

In [30]: data_ndarray = np.arange(0, 1000000)
 
In [31]: %timeit np.searchsorted(data_ndarray, 99999)
The slowest run took 16.04 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 996 ns per loop
 
In [32]: %timeit np.searchsorted(data_ndarray, 8888)
The slowest run took 18.22 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 994 ns per loop
 
In [33]: %timeit np.searchsorted(data_ndarray, 777777)
The slowest run took 31.32 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 990 ns per loop

numpy.searchsorted 可以同时搜索多个值:

>>> np.searchsorted([1,2,3,4,5], 3)
2
>>> np.searchsorted([1,2,3,4,5], 3, side='right')
3
>>> np.searchsorted([1,2,3,4,5], [-10, 10, 2, 3])
array([0, 5, 1, 2])

 

       

       其对应的插入函数是 insort_left  和 insort_right :

       

       可见,单纯看其结果的话,两个函数的操作结果是一样的,其实插入的位置不同而已。

分数成绩查询

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]])

 

posted @ 2018-01-11 22:08  Erick-LONG  阅读(224)  评论(0编辑  收藏  举报