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 Falsereturn 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 返回值:1bisect.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_left和insort_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]
共勉: 东汉·班固《汉书·枚乘传》:“泰山之管穿石,单极之绠断干。水非石之钻,索非木之锯,渐靡使之然也。”
-----指水滴不断地滴,可以滴穿石头;
-----比喻坚持不懈,集细微的力量也能成就难能的功劳。
----感谢读者的阅读和学习,谢谢大家。