TL;DR 本文将介绍Python bisect模块在某些场景下的妙用,可以高效和优雅的改善原有使用if-else才能解决问题。
难题:查询整数所属的区间
应用开发过程中,经常出现一种情景,需要你查询一个整数落在哪一个范围内,比如根据消费金额确定优惠金额或者打折力度等。具体的例子有:消费满100元优惠10元,消费满200元优惠25元,等等。
常规解决方案及其缺点
通常情况下,都是使用switch/if-elif来解决的,范围比较少的情况,代码还属于比较简洁的,当范围的数量增加,代码就变的相当的不简洁了,正如下面的代码:
1 | discount = None |
基于bisect的方案
bisect介绍
bisect是python的标准模块,是一个关于数组二分查找法的库,里面提供了在这里非常有用的三个函数bisect_left
, bisect_right
, bisect
. 这三个参数都接受一个array和一个数字,返回将数字插入这个array后这个数字的位置(index),但并不真正执行插入操作。比如:
1 | In[0]: import bisect |
表示如果将2插入1 3 5中间,那么插进去之后的index则为返回值(本例,返回值为1),如果出现相同的值,bisect()
函数选择将值插在后面也就是原有值的右侧:
1 | In[0]: import bisect |
bisect_left()
函数选择将值插在前面也就是原有值的左侧:
1 | In[0]: import bisect |
另外bisect_right()
函数是bisect()
函数的别名,或者反之。
利用bisect查找整数范围
bisect函数是二分查找,既可以用来插入,当然也可以用来检索信息,比如查找值所属的区段/区间。
前面我们提到的那个函数就可以利用bisect做改写:
1 | mapping = { |
这种方案在业务方案多变,查询范围特别多的情况下具备极大的可维护性和性能优势。