美文网首页
Python 中更优雅的范围判断

Python 中更优雅的范围判断

作者: kingron | 来源:发表于2021-12-15 17:45 被阅读0次

    问题

    一个常见的问题,班里的成绩分为 A、B、C、D、E 五等,分别对应 100-90 分,89-80 分,79-70 分,69-60 分,60 分以下。现在我们得到的数据是 66、33 等这样的数值,要根据数值找到对应的等级,通常情况下,我们会这样写:

    def get_grade(score):
        if 90 <= score <= 100:
            return 'A'
        elif 80 <= score < 90:
            return 'B'
        elif 70 <= score < 80:
            return 'C'
        elif 60 <= score < 70:
            return 'D'
        elif score < 60:
            return 'E'
    

    问题是,这样写代码会显得太丑陋了。那么,有没有更好的方法呢?

    解决方案

    标准库的 bisect 模块提供了一个很好的方法可以为此提供更为优雅的解决方案:bisect(),示例如下:

    from bisect import bisect
    
    breakpoints = 60, 70, 80, 90
    grades = 'EDCBA'
    
    
    def get_grade(score):
        return grades[bisect(breakpoints, score)]
    

    来试试效果:

    >>> [get_grade(s) for s in [33, 55, 66, 99]]
    ['E', 'E', 'D', 'A']
    

    结果正如预期。

    扩展

    • bisect.bisect(a, x, lo=0, hi=len(a)) 返回的插入点 i 将数组 a 分成两半,使得左半边为 all(val <= x for val in a[lo : i]) 而右半边为 all(val > x for val in a[i : hi])
    • bisect 正如其名称一样,使用了二分算法,二分法对于搜索一定范围的值是很高效的。 对于定位特定的值,则字典的性能更好,比如考虑根据等级获取对应的数值范围,使用下面的代码更为高效:
    grades_scale = {'A': (90, 100),
                    'B': (80, 89),
                    'C': (70, 79),
                    'D': (60, 69),
                    'E': (0, 59)}
    
    
    def get_scale(grade):
        """获取等级对应的成绩范围"""
        return grades_scale[grade]
    

    相关文章

      网友评论

          本文标题:Python 中更优雅的范围判断

          本文链接:https://www.haomeiwen.com/subject/lmypfrtx.html