首页 > 其他分享 >不使用 if-elif 语句,如何优雅地判断某个数字所属的等级?

不使用 if-elif 语句,如何优雅地判断某个数字所属的等级?

时间:2022-10-14 13:39:46浏览次数:79  
标签:语句 elif bisect 优雅 60 查找 print scr

偶然看到了 stackoverflow 上的一个问题,还挺有启发,故分享一下。

题目大意是:有从 A 到 F 的 5 个等级,现要判断某个数值(从 0 到 1 之间)所属的等级。举例,如数值 >= 0.9,则属于 A;若数值 >= 0.8,则属于 B;以此类推。

若使用 if-elif 语句,可能会写成这样:

if scr >= 0.9:
print('A')
elif scr >= 0.8:
print('B')
elif scr >= 0.7:
print('C')
elif scr >= 0.6:
print('D')
else:
print('F')

此写法出现了很多重复的模式,不够简洁优雅。有什么更好的写法,来实现这个目的呢?

该问题下的回答挺多的,实现思路五花八门。我挑几个可读性比较好:

方法一:使用​​bisect​​ 模块(数字可调)

不使用 if-elif 语句,如何优雅地判断某个数字所属的等级?_折半查找

方法二:使用 zip() 与 next()

不使用 if-elif 语句,如何优雅地判断某个数字所属的等级?_折半查找_02

方法三:使用字典(仅适用于 Python 3.6 以上的有序字典)

不使用 if-elif 语句,如何优雅地判断某个数字所属的等级?_折半查找_03

还有其它几个回答,虽然都能实现数字分级的目的,但是其可读性要差很多,因为它们要么需要你作计算和推理,要么就是引入了额外的变量。

感兴趣的话,你可在这个地址查看全部答案:​​https://stackoverflow.com/questions/61030617/how-can-i-simplify-repetitive-if-elif-statements​

纵观全部答案后,我认为还是使用​​bisect​​ 的方法最高效优雅,不愧是它获得了最高的赞同票。

这里简单分析下它的实现过程。

​bisect​​ 是 Python 内置的标准库,实现了二分查找算法。所谓二分查找,也被称为“折半查找”(Binary Search),其基本思想是把有序排列的 n 个元素平均分成两半,然后将待查找的 x 与中间元素比较,若 x 小于中间元素,则将左半段二分,再将 x 与其中间元素比对,以此类推。

这是一个简单的图示例子:

不使用 if-elif 语句,如何优雅地判断某个数字所属的等级?_二分查找算法_04

​bisect​​ 库中的 bisect() 方法,查找元素 x 在一个升序序列中的插入点 i,使得插入点左侧的元素都小于等于 x,插入点右侧的元素都大于 x。

对照前面的例子:

from bisect import bisect 

def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
i = bisect(breakpoints, score)
return grades[i]

可以化简成两部分:

  • bisect([60, 70, 80, 90], score),返回插入点的值。假如 score 是 59,计算得出插入点在 60 的左侧,而 Python 列表的索引值是以 0 开始,所以返回插入点的值为 0;假如 score 是 60,计算得出插入点在 60 的右侧,即返回索引值为 1。
  • 'FDCBA'[i],返回索引值为 i 的字符。假如 i 是 0,得到“F”;假如 i 是 3,得到“B”……

二分查找算法是效率较高的算法,时间复杂度为 O(logn)。该题目的查找范围很小,所以时间效率差别不大。但是其写法称得上是 Pythonic,值得借鉴。

另外,再看看前面的方法三(使用字典),它的可读性很强,即顺次将 scr 与字典中的值比较(从高往低,即 0.9~0.5),以此得出对应的键值。(PS:它多分了一个“E”级,可去掉)

如果 Python 版本低于 3.6,则 grades.items() 会是无序的,将会破坏比较的顺序。为了兼容性,可以修改成 sorted(grades.items()):

不使用 if-elif 语句,如何优雅地判断某个数字所属的等级?_折半查找_05

这种写法没有引入额外的库,使用的 items() 与 sorted() 都是基础知识(相比于方法二的 zip() 与 next()),简单实用,也非常值得推荐。

不管怎么说,反复使用 if-elif 语句的判断方式是挺笨拙的,必须改进。文中列出的都是目前比较受认可的回答。

如果有面试官把它作为面试题,我觉得会挺有意思:难度不大,有发挥空间。

读者们可有其它想法?欢迎留言讨论。



标签:语句,elif,bisect,优雅,60,查找,print,scr
From: https://blog.51cto.com/u_14244765/5756322

相关文章

  • Python 为什么要有 pass 语句?
    本文出自“Python为什么”系列,请查看​​全部文章​​关于Python中的​​pass​​语句,它似乎很简单(只有4个字母),即使是没有任何编程经验的初学者也能很快地掌握它的用法......
  • Python 为什么只需一条语句“a,b=b,a”,就能直接交换两个变量?
    从接触Python时起,我就觉得Python的元组解包(unpacking)挺有意思,非常简洁好用。最显而易见的例子就是多重赋值,即在一条语句中同时给多个变量赋值:>>>x,y=1,2>>>print(......
  • 546 JDBC练习_insert语句和547JDBC练习_update语句
    JDBC练习_insert语句publicstaticvoidmain(String[]args)throwsException{Statementstmt=null;Connectionconn=null;try{......
  • ASP构造大数据量的分页SQL语句
     1<%@Language = "VBScript" Codepage = "936"%> 2<% 3'分页sql语句生成代码 4Fun......
  • 教你优雅的实现 SpringBoot 并行任务
    SpringBoot的定时任务:第一种:把参数配置到.properties文件中:代码:packagecom.accord.task;importjava.text.SimpleDateFormat;importjava.util.Date;importorg.spring......
  • MySQL基础架构及一条SQL查询语句是如何执行的
    MySQL基础架构及一条SQL查询语句是如何执行的该文摘抄自林晓斌老师的文章MySQL的基本架构示意图,从中你可以清楚地看到SQL语句在MySQL的各个功能模块中的执行过程......
  • KodeLife | Shader 实时编辑预览的强大工具使用实践
    公众号回复:666,领取学习资源大礼包经常有朋友在群里面问想学习Shader有什么工具可以推荐?今天它来了~~~推荐一款强大的Shader实时编辑预览的工具——​​KodeLife​​......
  • Python 为什么不支持 switch 语句?
    本文出自“Python为什么”系列,请查看​​全部文章​​在这篇文章里,我们会聊一聊为什么Python决定不支持switch语句。为什么想要聊这个话题呢?主要是因为switch在其它语......
  • 【JS】80-如何优雅处理前端异常?
    前端一直是距离用户最近的一层,随着产品的日益完善,我们会更加注重用户体验,而前端异常却如鲠在喉,甚是烦人。一、为什么要处理异常?异常是不可控的,会影响最终的呈现结果,但是我们......
  • mysql语句-----函数使用
    总结常用函数及使用方法1.字符串相关函数  --返回字符串字符集CHARSET(str)selectcharset(ename)fromemp;--连接字符串CONCAT(string[,…])selectc......