bisect
bisect模块实现了二分查找和插入算法
我们可以看一下bisect模块的源码。
1 | """Bisection algorithms.""" |
这可能是Python初学者少有的能快速看懂的标准库源代码。整个模块去掉注释语句,就这么多行代码。
bisect = bisect_right
这一行其实就是个alias,用于向后兼容。
最后的try、except语句为我们提供了用C语言重写算法的钩子。
方法介绍
bisect模块采用经典的二分算法查找元素。模块提供下面几个方法:
bisect.bisect_left(a, x, lo=0, hi=len(a))
定位x在序列a中的插入点,并保持原来的有序状态不变。参数lo和hi用于指定查找区间。如果x已经存在于a中,那么插入点在已存在元素的左边。函数的返回值是列表的整数下标。
bisect.bisect_right(a, x, lo=0, hi=len(a))
和上面的区别是插入点在右边。函数的返回值依然是一个列表下标整数。
bisect.bisect(a, x, lo=0, hi=len(a))
等同于bisect_right()。
注意,前面这三个方法都是获取插入位置,也就是列表的某个下标的,并不实际插入。但下面三个方法实际插入元素,没有返回值。
bisect.insort_left(a, x, lo=0, hi=len(a))
将x插入有序序列a内,并保持有序状态。相当于a.insert(bisect.bisect_left(a, x, lo, hi), x)
。碰到相同的元素则插入到元素的左边。这个操作通常是 O(log n) 的时间复杂度。
bisect.insort_right(a, x, lo=0, hi=len(a))
同上,只不过碰到相同的元素则插入到元素的右边。
bisect.insort(a, x, lo=0, hi=len(a))
等同于insort_right()。
实例展示:
1 | import bisect |
下面是一个bisect和random配合的例子:
1 | import bisect |
下面的5个例子是利用bisect模块实现通用的列表元素查询方法:
1 | def index(a, x): |
下面是一个利用bisect自动由百分制成绩转换为ABCD等级的方法:90 以上是‘A’, 80 -89 是‘B’,
1 | def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'): |
另外一个例子
1 | 'red', 5), ('blue', 1), ('yellow', 8), ('black', 0)] data = [( |