如何用调度表等优雅方式实现分数区间的函数分发?
问题描述
我有一个表示学生总分的整数 0 <= x <= 100,需要根据分数所在区间评定等级并执行对应逻辑。原本的代码写法如下:
if 0 <= grade <= 39: do_f() elif 40 <= grade <= 60: do_b() elif 60 <= grade <= 100: do_a()
但这种写法存在问题:若新增更多等级,会陷入if-else嵌套的混乱。请问如何使用调度表或其他优雅高效的方式改写这段代码?
解决方案
方法一:区间匹配调度表
把分数区间和对应执行函数整理成列表,按分数从高到低排序,遍历找到第一个符合条件的区间执行逻辑。新增等级时只需往列表加条目,不用修改判断逻辑:
def do_f(): print("不及格") def do_b(): print("中等") def do_a(): print("优秀") grade_schedule = [ (60, 100, do_a), (40, 60, do_b), (0, 39, do_f) ] def handle_grade(grade): for lower, upper, func in grade_schedule: if lower <= grade <= upper: func() return # 可选:处理超出范围的分数 print("分数无效") # 调用示例 handle_grade(75) # 输出:优秀 handle_grade(50) # 输出:中等 handle_grade(20) # 输出:不及格
方法二:bisect模块高效查找
如果区间连续无重叠,用bisect模块快速定位等级,适合等级较多的场景,查找效率更高:
import bisect def do_f(): print("不及格") def do_b(): print("中等") def do_a(): print("优秀") # 区间临界点(升序排列) cutoffs = [40, 60] # 对应临界点的函数,逻辑:<40→do_f;40<=x<60→do_b;>=60→do_a grade_funcs = [do_f, do_b, do_a] def handle_grade(grade): if not 0 <= grade <= 100: print("分数无效") return idx = bisect.bisect_right(cutoffs, grade) grade_funcs[idx]() # 调用示例 handle_grade(39) # 输出:不及格 handle_grade(40) # 输出:中等 handle_grade(60) # 输出:优秀
方法三:类封装可扩展方案
如果需要每个等级附带额外信息(比如等级描述),用类封装规则,扩展性更强:
class GradeRule: def __init__(self, lower, upper, func, description): self.lower = lower self.upper = upper self.func = func self.description = description def matches(self, grade): return self.lower <= grade <= self.upper def do_f(): print("执行不及格对应逻辑") def do_b(): print("执行中等对应逻辑") def do_a(): print("执行优秀对应逻辑") # 初始化规则列表 grade_rules = [ GradeRule(60, 100, do_a, "优秀"), GradeRule(40, 60, do_b, "中等"), GradeRule(0, 39, do_f, "不及格") ] def handle_grade(grade): for rule in grade_rules: if rule.matches(grade): print(f"等级:{rule.description}") rule.func() return print("分数无效") # 调用示例 handle_grade(85)
内容的提问来源于stack exchange,提问作者Chukwujiobi Canon
相关产品推荐
相关产品推荐

