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

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

题目大意是:有从 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 模块(数字可调)

979162c9cfbf06e6b2af9ecd2b7586f.png

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

966b94755461fe5a7fc66eeb2bb3690.png

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

e8d67ab0fb88d1bc2003d2fdbf6928d.png

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

感兴趣的话,你可在这个地址查看全部答案:stackoverflow.com/questions/6…

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

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

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

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

b8f7c451a6443e0f46938e164df85c3.png

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()):

c68e97df493a58766147e4f6de9858d.png

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

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


目录
相关文章
|
11月前
阿里云RPA元素出现后,有个返回结果 ,需要拿这个结果再去做判断吗?这个判断的操作 如何 处理
【2月更文挑战第8天】阿里云RPA元素出现后,有个返回结果 ,需要拿这个结果再去做判断吗?这个判断的操作 如何 处理
168 3
|
11月前
|
Python
使用 if...elif...else 语句判断数字是
使用 if...elif...else 语句判断数字是
|
11月前
判断字符类型
该内容描述了一个字符判断和转换的逻辑:输入字符,根据条件进行操作。如果字符是大写字母,转为小写;如果是小写字母,转为大写;若是数字,输出其ASCII值;否则输出"错误"。判断条件包括:大写字母ASCII值在'A'和'Z'之间,小写字母在'a'和'z'之间,数字在'0'和'9'之间。转换利用ASCII值差32的特性,通过if-else if语句实现。内容中还包括两幅示例图片,显示了程序执行的结果。
73 1
|
9月前
|
前端开发
let array = [{id:‘001‘,name:‘小新‘,age:5},{ id:‘002‘,name:‘小葵‘]这样数据如何遍历,拿到其中一个值,数组中装对象如何获取其中一个固定的值
let array = [{id:‘001‘,name:‘小新‘,age:5},{ id:‘002‘,name:‘小葵‘]这样数据如何遍历,拿到其中一个值,数组中装对象如何获取其中一个固定的值
|
9月前
|
语音技术 数据安全/隐私保护 Python
语音识别---数据输入(input语句),布尔类型和比较运算符,if语句的基本格式,Python通过空格缩进来判断代码块的归属关系,我要买票吗讲解?if_elif_else
语音识别---数据输入(input语句),布尔类型和比较运算符,if语句的基本格式,Python通过空格缩进来判断代码块的归属关系,我要买票吗讲解?if_elif_else
下列给定程序中函数fun的功能是:统计substr所指的子符串在str所指的字符串中出现的次数。
下列给定程序中函数fun的功能是:统计substr所指的子符串在str所指的字符串中出现的次数。
114 0
|
存储 JavaScript 前端开发
【JS交互埋坑】事件函数自动将数字字符串String转为数值Number
【JS交互埋坑】事件函数自动将数字字符串String转为数值Number
128 0
根据select下拉框值判断验证条件
根据select下拉框值判断验证条件
71 0
求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加由键盘控制
求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加由键盘控制
790 0
求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加由键盘控制
整数值比较判断登录系统用户
整数值比较判断登录系统用户
66 0

热门文章

最新文章