之前实现了一个函数功能,大意是根据不同的时间天数,返回不同的值。
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是?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'],两个列表一一对应。
这样我们将时间天数插入到列表中得到左边的索引,然后就能根据索引得到返回值。
?函数优化如下:
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
以下是一个举例:
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]
共勉: 东汉·班固《汉书·枚乘传》:“泰山之管穿石,单极之绠断干。水非石之钻,索非木之锯,渐靡使之然也。”
-----指水滴不断地滴,可以滴穿石头;
-----比喻坚持不懈,集细微的力量也能成就难能的功劳。
----感谢读者的阅读和学习,谢谢大家。