原地删除字典列表中name、age、group均重复的字典,现有代码报错
问题分析与修正
原代码存在三个关键问题:
- 语法错误:
a.pop[j]是错误写法,列表的pop是方法,必须用括号调用,正确写法是a.pop(j)。 - 匹配逻辑错误:原代码用
a[i] == a[j]比较整个字典,但需求只要求name、age、group三个字段值相同就算重复,和points等其他字段无关。 - 遍历索引混乱:正向遍历列表时删除元素,会导致列表长度动态变化,后续的索引会跳过元素或引发索引越界错误。
修正后的高效代码
a = [ {"name": "Tom", "age": 21,"group":"sdd","points":0}, {"name": "Mark", "age": 5,"group":"sdo","points":0}, {"name": "Pam", "age": 7,"group":"spp","points":0}, {"name": "Tom", "age": 21,"group":"sdd","points":10}, # 仅points不同,仍判定为重复 {"name": "Buke", "age": 31,"group":"pool","points":0} ] print("原列表:", a) seen = set() # 反向遍历索引,避免删除元素导致的索引偏移问题 for i in range(len(a)-1, -1, -1): current_dict = a[i] # 提取指定字段组成元组作为判断重复的键 key_tuple = (current_dict["name"], current_dict["age"], current_dict["group"]) if key_tuple in seen: a.pop(i) else: seen.add(key_tuple) print("去重后列表:", a)
代码说明
- 反向遍历:从列表末尾往前遍历,删除元素时不会影响未处理的前置元素索引,彻底避免索引越界或漏处理的问题。
- 集合去重:用集合存储已出现过的
name-age-group组合,集合查询效率为O(1),比嵌套循环的O(n²)效率更高。 - 精准匹配:严格按照需求只校验指定的三个字段,忽略其他字段的差异。
嵌套循环方式的修复(兼容原思路)
如果一定要沿用嵌套循环的逻辑,需调整遍历方向避免索引混乱:
a = [ {"name": "Tom", "age": 21,"group":"sdd","points":0}, {"name": "Mark", "age": 5,"group":"sdo","points":0}, {"name": "Pam", "age": 7,"group":"spp","points":0}, {"name": "Tom", "age": 21,"group":"sdd","points":0}, {"name": "Buke", "age": 31,"group":"pool","points":0} ] print("原列表:", a) # 反向遍历外层索引i for i in range(len(a)-1, -1, -1): # 反向遍历i之前的元素索引j for j in range(i-1, -1, -1): # 仅校验指定的三个字段 if (a[i]["name"] == a[j]["name"] and a[i]["age"] == a[j]["age"] and a[i]["group"] == a[j]["group"]): a.pop(i) break # 找到重复后跳出内层循环,处理下一个i print("去重后列表:", a)
这种方式时间复杂度较高,仅适合小数据量场景,优先推荐第一种集合去重的方法。
内容的提问来源于stack exchange,提问作者Nethum
相关产品推荐
相关产品推荐

