Python按条件拆分字典为分组列表 末尾元素遗漏bug修复
字典分组问题修复方案
问题场景
现有两个字典product与types,需按规则将product字典按顺序拆分为多个列表分组:
product = { 'k1': 30.99999999999994, 'k2': 400.0, 'k3': 50.0, 'k4': 400.00000000000006, 'k5': 400.0, 'k6': 50.0, 'k7': 60.0, 'k8': 300.0, 'k9': 40.0} types = { 'k1': 2, 'k2': 1, 'k3': 1, 'k4': 1, 'k5': 1, 'k6': 1, 'k7': 1, 'k8': 1, 'k9': 2}
分组规则:
- 规则1:若产品value小于200,可与其他产品合并,合并后新分组的总value需小于600
- 规则2:types值不同的产品不可合并到同一分组
原有代码问题
原有实现对末尾索引的处理存在逻辑漏洞,运行后会遗漏最后一个产品k9,错误结果如下:
ProductValue = [[30.99999999999994], [400.0, 50.0], [400.00000000000006], [400.0, 50.0, 60.0], [300.0]] ProductName = [['k1'], ['k2', 'k3'], ['k4'], ['k5', 'k6', 'k7'], ['k8']]
原有错误代码:
k = list(product.keys()) ProductValue = [] ProductName = [] for idx, name in enumerate(k): value = product[name] if idx == 0: temp1 = [value] temp2 = [name] continue if idx == len(k) - 1: ProductValue.append(temp1) ProductName.append(temp2) continue if value < 200 or product[k[idx - 1]] < 200: sec1 = types[k[idx - 1]] sec2 = types[k[idx]] if ((sum(temp1) + value) > 600) or (sec1 != sec2): ProductValue.append(temp1) ProductName.append(temp2) temp1 = [value] temp2 = [name] continue else: temp1.append(value) temp2.append(name) else: ProductValue.append(temp1) ProductName.append(temp2) temp1 = [value] temp2 = [name]
核心bug点:
- 遍历到最后一个索引时,直接存入上一个临时分组,既不判断最后一个元素能否加入当前临时组,也不处理最后一个元素本身,直接导致k9丢失
- 类型校验仅对比相邻两个元素的type,没有和当前临时分组的全局type做对比,多元素分组时类型判断失效
- 遍历过程中没有统一的收尾逻辑,遍历结束后最后一个临时分组不会被自动存入结果集
正确实现代码
修复思路:
- 初始化时直接用第一个元素构建临时分组,记录分组的type,避免单独处理idx=0的冗余逻辑
- 从第二个元素开始顺序遍历,每个元素先校验是否满足合并条件:type与当前分组一致、加入后分组总值小于600(增加浮点误差容限避免精度问题)、满足合并的值规则,满足则加入当前分组
- 不满足合并条件时,先将当前临时分组存入结果,再用当前元素新建临时分组
- 全部遍历完成后,将最后剩余的临时分组存入结果,避免末尾元素遗漏
k = list(product.keys()) ProductValue = [] ProductName = [] if k: # 初始化第一个分组 current_val = [product[k[0]]] current_name = [k[0]] current_type = types[k[0]] eps = 1e-9 # 处理浮点数计算精度误差 for name in k[1:]: val = product[name] val_type = types[name] # 判断是否可以合并到当前分组 can_merge = True # 类型不同直接不能合并 if val_type != current_type: can_merge = False else: total = sum(current_val) + val # 合并后总值超过600(考虑浮点误差)不能合并 if total - 600 > eps: can_merge = False # 如果当前值>=200,且当前分组已有元素,不能合并 elif val >= 200 and len(current_val) > 0: can_merge = False if can_merge: current_val.append(val) current_name.append(name) else: # 保存当前分组,新建分组 ProductValue.append(current_val) ProductName.append(current_name) current_val = [val] current_name = [name] current_type = val_type # 遍历结束后追加最后一个分组 ProductValue.append(current_val) ProductName.append(current_name) # 输出结果验证 print(ProductValue) print(ProductName)
运行后得到正确结果:
ProductValue = [ [30.99999999999994], [400.0, 50.0], [400.00000000000006], [400.0, 50.0, 60.0], [300.0], [40.0] ] ProductName = [ ['k1'], ['k2', 'k3'], ['k4'], ['k5', 'k6', 'k7'], ['k8'], ['k9'] ]
内容的提问来源于stack exchange,提问作者sohailnewpythonprogrammer
相关产品推荐
相关产品推荐

