如何简化含多条件多if语句的测试分数对比函数?
问题描述
我有一个用于输出哪些测试分数显著高于其他测试分数的函数。共有四项测试(a、b、c、d),用户输入测试分数,并勾选对应复选框以标记任意测试分数间存在显著差异,总计6个复选框:"a & b"、"a & c"、"a & d"等,用户预先知晓所有相关信息。
当前函数可正常运行,但为覆盖所有情况,需要编写大量if语句:
def my_function (A_test_score, B_test_score, C_test_score, D_test_score, A_B_state, A_C_state, A_D_state, B_C_state, B_D_state, C_D_state): A_test_score = int(a.get()) B_test_score = int(b.get()) C_test_score = int(c.get()) D_test_score = int(d.get()) # Retrieving state of the checkboxes (1 = checked) A_B_state = A_B_var.get() A_C_state = A_C_var.get() A_D_state = A_D_var.get() B_C_state = B_C_var.get() B_D_state = B_D_var.get() C_D_state = C_D_var.get() final_text = "" if A_B_state == 1: if (A_test_score - B_test_score) > 0: final_text += "A is significantly larger than B" elif (A_test_score - B_test_score) < 0: final_text += "B is significantly larger than A" if A_C_state == 1: if (A_test_score - C_test_score) > 0: final_text += "\nA is significantly larger than C" elif (A_test_score - C_test_score) < 0: final_text += "\nC is significantly larger than A" … # and so on… if A_B_state == 1 and (A_test_score - B_test_score) > 0 and A_C_state == 1 and (A_test_score - C_test_score) > 0 and A_D_state == 1 and (A_test_score - D_test_score) > 0: return "A is significantly larger than B, C and D" if A_B_state == 1 and (A_test_score - B_test_score) > 0 and A_C_state == 1 and (A_test_score - C_test_score) > 0: return "A is significantly larger than B and C" return final_text
期望输出
例如,若测试a和b的分数显著高于c和d,输出:"a and b are significantly larger than c and d."
又如,若a分数高于b、c、d,且b分数高于d,输出:
a is significantly larger than b, c and d. b is larger than d.
目标是避免如下冗余输出:
a is significantly larger than b. a is significantly larger than c. a is significantly larger than d.
我猜测存在更优实现方式,但未找到相关方案,求思路建议。
优化思路与实现方案
1. 结构化存储数据,减少重复代码
先把测试项、分数和复选框状态用结构化数据统一管理,避免单独处理每个变量:
# 整理测试项与对应分数 tests = { 'A': int(a.get()), 'B': int(b.get()), 'C': int(c.get()), 'D': int(d.get()) } # 整理所有复选框的对比关系与状态 comparisons = [ ('A', 'B', A_B_var.get()), ('A', 'C', A_C_var.get()), ('A', 'D', A_D_var.get()), ('B', 'C', B_C_var.get()), ('B', 'D', B_D_var.get()), ('C', 'D', C_D_var.get()) ]
2. 构建分数的层级优势关系
筛选出所有被标记为显著差异的对比,为每个测试项记录它显著大于的所有其他项:
# 初始化每个测试项的"大于集合" greater_than = {test: set() for test in tests} for x, y, state in comparisons: if state != 1: continue # 跳过未勾选的对比项 if tests[x] > tests[y]: greater_than[x].add(y) elif tests[x] < tests[y]: greater_than[y].add(x)
3. 合并重复表述,生成简洁自然的文本
核心是把每个测试项的"大于集合"合并成符合日常表达的语句,同时避免重复描述:
def format_group(items): """把列表格式化为自然语言,比如['B','C','D']变成'B, C and D'""" items = sorted(items) if len(items) == 1: return items[0] elif len(items) == 2: return f"{items[0]} and {items[1]}" else: return ", ".join(items[:-1]) + f" and {items[-1]}" final_lines = [] processed = set() # 记录已处理的测试项,避免重复输出 # 先处理多组共同大于或单组大于多个的情况 for test in sorted(tests.keys()): targets = greater_than[test] if not targets or test in processed: continue # 检查是否有其他测试项和当前项有完全相同的"大于集合" matching_tests = [t for t in tests.keys() if t != test and greater_than[t] == targets] if matching_tests: # 多个测试项共同大于一组 combined_tests = sorted([test] + matching_tests) line = f"{format_group(combined_tests)} are significantly larger than {format_group(targets)}." final_lines.append(line) processed.update(combined_tests) else: # 单个测试项大于一组 line = f"{test} is significantly larger than {format_group(targets)}." final_lines.append(line) processed.add(test) # 处理剩余未被合并的独立小关系(比如B>D这类未被上级关系覆盖的情况) for x in sorted(tests.keys()): for y in sorted(greater_than[x]): # 确保x未被处理,且y不在已处理项的"大于集合"中(避免重复) if x not in processed and y not in {item for p in processed for item in greater_than[p]}: line = f"{x} is significantly larger than {y}." final_lines.append(line) processed.add(x) # 拼接所有行成最终文本 final_text = "\n".join(final_lines) return final_text
4. 关键逻辑说明
- 结构化存储:用字典和列表统一管理测试项与对比关系,彻底消除大量重复的if判断。
- 层级关系构建:通过集合记录每个测试项的优势项,为后续合并提供清晰的数据基础。
- 自然语言格式化:辅助函数
format_group负责把集合转换成符合日常表达的文本,处理单元素、双元素和多元素的不同格式。 - 去重处理:
processed集合避免重复输出已经合并过的关系,确保最终文本简洁无冗余。
内容的提问来源于stack exchange,提问作者Cartilago
相关产品推荐
相关产品推荐

