单位符号分数化简函数异常:结果不符合测试预期
问题:带单位的无系数分数化简函数错误排查
我正在编写一个化简带符号(如"kg")的无系数分数的函数,函数接收两个参数:第一个列表包含分子中的所有单位,第二个列表包含分母中的所有单位。大部分功能已完成,但部分测试用例未通过——比如分子与分母单位完全相同时,未返回预期的(['1'], ['1']);还有一个测试用例返回了(['1', '1', 's'], ['s']),而非预期的(['1'], ['1'])。
我的代码
def canonical(unit): numerador = unit[0] denominador = unit[1] numerador.sort() denominador.sort() lstNumerador = numerador lstDenominador = denominador for i in numerador: for j in denominador: if i == j: lstNumerador.remove(i) lstDenominador.remove(j) if lstNumerador.count('1') > 0: lstNumerador.remove('1') if lstDenominador.count('1') > 0: lstDenominador.remove('1') if len(lstNumerador) == 0: lstNumerador.append('1') if len(lstDenominador) == 0: lstDenominador.append('1') unit = (lstNumerador, lstDenominador) return unit
测试用例
预期输出
unit = (['kg', 'm', 'm', 's'], ['m', 's', 's']) print(canonical(unit)) #(['kg', 'm'], ['s']) unit = (['kg', 'm', 'm', 's'], ['s', 'm', 'm', 'kg']) print(canonical(unit)) #(['1'], ['1']) unit = (['s', 'kg', 'm', '1'], ['1', '1']) print(canonical(unit)) #(['kg', 'm', 's'], ['1']) unit = (['1', 'm', 's', '1', '1'], ['m', 's']) print(canonical(unit)) #(['1'], ['1']) unit = (['kg', 'm', 'm'], ['kg', 'm', 'm']) print(canonical(unit)) #(['1'], ['1'])
实际输出
(['kg', 'm'], ['s']) (['m', 's'], ['m', 's']) (['kg', 'm', 's'], ['1']) (['1', '1', 's'], ['s']) (['m'], ['m'])
问题分析与修复
你的代码存在两个核心问题:
- 遍历与修改原列表冲突:
lstNumerador = numerador是引用赋值,并非创建新列表,遍历原列表时直接修改会导致遍历跳过部分元素;嵌套循环的匹配方式还会重复抵消,导致部分单位未被正确处理。 - '1'的处理顺序错误:应该先移除所有'1'再做单位抵消,而非抵消后再处理,否则'1'会干扰抵消逻辑。
修复后的代码:
def canonical(unit): # 拷贝原列表并排序,避免修改原数据 numerador = sorted(unit[0].copy()) denominador = sorted(unit[1].copy()) # 先移除所有'1',因为'1'不参与单位抵消 while '1' in numerador: numerador.remove('1') while '1' in denominador: denominador.remove('1') # 遍历分子副本,逐个抵消分母中的相同单位 num_copy = numerador.copy() for unit_item in num_copy: if unit_item in denominador: numerador.remove(unit_item) denominador.remove(unit_item) # 空列表补'1' if not numerador: numerador.append('1') if not denominador: denominador.append('1') return (numerador, denominador)
修复说明
- 列表拷贝:用
.copy()创建独立副本,避免遍历和修改操作互相干扰。 - 提前清理'1':先移除所有'1',避免其干扰后续单位抵消逻辑。
- 精准抵消:遍历分子的副本,逐个检查并抵消分母中的相同单位,确保每个单位只被处理一次。
内容的提问来源于stack exchange,提问作者Tumes
相关产品推荐
相关产品推荐

