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

发布时间:2023年12月28日

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]

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

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

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

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

文章来源:https://blog.csdn.net/kymppcds/article/details/135256722
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。