python的二分查找库bisect,可用于简化繁琐的if条件分支

if条件分支的函数

之前实现了一个函数功能,大意是根据不同的时间天数,返回不同的值。

def analyse_value(days_num:int):
   if days_num == 1:
       value = 'RD1d'
   elif days_num > 1 and days_num <= 7:
       value = 'RD7d'
   elif days_num > 7 and days_num <= 14:
       value = 'RD14d'
   elif days_num > 14 and days_num <= 21:
       value = 'RD21d'
   elif days_num > 21 and days_num <= 30:
       value = 'RD1m'
   elif days_num > 30 and days_num <= 60:
       value = 'RD2m'
   elif days_num > 60 and days_num <= 90:
       value = 'RD3m'
   elif days_num > 90 and days_num <= 180:
       value = 'RD6m'
   elif days_num > 180 and days_num <= 365:
       value = 'RD1y'
   else:
       print('.....ERROR:输入值不在范围')
       return False
   return value

函数运行结果:

print(f'输入天数:1 返回值:{analyse_value(1)}')
print(f'输入天数:7 返回值:{analyse_value(7)}')
print(f'输入天数:8 返回值:{analyse_value(8)}')
print(f'输入天数:14 返回值:{analyse_value(14)}')
print(f'输入天数:90 返回值:{analyse_value(90)}')

print(f'输入天数:91 返回值:{analyse_value(91)}')

#结果如下

输入天数:1 返回值:RD1d

输入天数:7 返回值:RD7d

输入天数:8 返回值:RD14d

输入天数:14 返回值:RD14d

输入天数:90 返回值:RD3m

输入天数:91 返回值:RD6m

函数本身很简单,输入一个数字,经过不同的if条件分支判断,返回约定的值。

这样看上去比较简单易懂,但是实际上条件分支较多,想着如何优化下,也搜了一些资料,发现了python自带的二分查找库bisect,正好可以解决这个问题。

bisect 库简要介绍

bisect是 python 内置模块,用于有序序列的插入和查找。

bisect是实现 二分 (bisection) 算法 的模块,能够保持序列顺序不变的情况下对其进行 二分查找和插入

分析:上面的函数中,我们用到的天数分别是1,7,14,21,30,60,90,180,365,判断条件中基本都是统一的判断逻辑:数字都是大于1个值,同时小于等于另一个值。

那么正好可以使用到bisect中的bisect_left函数,该函数的作用是在有序列表中查找将值插入的位置,并返回左侧的索引(相同值的最左边位置)

比较难理解,我们举个例子:

列表a :[1,6,8]   数字6插入到列表中,因为已经有一个数字6,bisect_left函数返回列表中数字6的索引为1,而如果使用bisect或者bisect_right函数返回的是数字6右边对应的索引为2。

lista = [1,6,8]
print(f'bisect.bisect_left 返回值:{bisect.bisect_left(lista,6)}')
print(f'bisect.bisect_right  返回值:{bisect.bisect_right(lista,6)}')

结果:

bisect.bisect_left 返回值:1

bisect.bisect_right  返回值:2

基于以上理解我们将上面的天数定义为一个列表[1,7,14,21,30,60,90,180,365],将返回值也定义为一个列表['RD1d','RD7d','RD14d','RD21d','RD1m','RD2m','RD6m','RD3m','RD6m','RD1y'],两个列表一一对应。

这样我们将时间天数插入到列表中得到左边的索引,然后就能根据索引得到返回值。

使用bisect_left函数

 函数优化如下:


def analyse_value(days_num:int):
   lista = [1,7,14,21,30,60,90,180,365]
   listb = ['RD1d','RD7d','RD14d','RD21d','RD1m','RD2m','RD3m','RD6m','RD1y']
   return listb[bisect.bisect_left(lista,days_num)]

还是输入同样的天数,我们看下结果跟原函数结果一致。

print(f'输入天数:1 返回值:{analyse_value(1)}')
print(f'输入天数:7 返回值:{analyse_value(7)}')
print(f'输入天数:8 返回值:{analyse_value(8)}')
print(f'输入天数:14 返回值:{analyse_value(14)}')
print(f'输入天数:90 返回值:{analyse_value(90)}')
print(f'输入天数:91 返回值:{analyse_value(91)}')

结果:得到的结果跟原函数值是一致的。

输入天数:1 返回值:RD1d

输入天数:7 返回值:RD7d

输入天数:8 返回值:RD14d

输入天数:14 返回值:RD14d

输入天数:90 返回值:RD3m

输入天数:91 返回值:RD6m

bisect其他函数insort_leftinsort_right是将某个值插入到有序列表的最左侧或者最右侧

以下是一个举例:

lista = [1,6,8]
bisect.insort_left(lista,5)
print(f'bisect.insort_left插入后列表:{lista}')
bisect.insort_right(lista,7)
print(f'bisect.insort_left插入后列表:{lista}')

结果:

bisect.insort_left插入后列表:[1, 5, 6, 8]

bisect.insort_left插入后列表:[1, 5, 6, 7, 8]

共勉: 东汉·班固《汉书·枚乘传》:“泰山之管穿石,单极之绠断干。水非石之钻,索非木之锯,渐靡使之然也。”

-----指水滴不断地滴,可以滴穿石头;

-----比喻坚持不懈,集细微的力量也能成就难能的功劳。

----感谢读者的阅读和学习,谢谢大家。

  • 20
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值