如何在字典列表中按名称标识分组查找同ID的重复项
如何按分组标识和ID找出字典列表中的重复项对
现有字典列表list1,需要分别找出名称包含gr1、gr2、gr3、pl1、ps1且ID相同的项对,并按指定格式输出。以下是示例数据、尝试代码、错误输出及期望输出,附正确实现方案。
示例列表
list1 = [ {'name': 'saeed1-gr1', 'id': 1}, {'name': 'pl1-saeed1', 'id': 1}, {'name': 'saeed11-gr2', 'id': 8}, {'name': 'pl1-saeed2', 'id': 2}, {'name': 'saeed3-gr2', 'id': 8}, {'name': 'saeed5-gr1', 'id': 3}, {'name': 'pl1-saeed7', 'id': 1}, {'name': 'saeed15-gr1', 'id': 1}, {'name': 'ps1-saeed15', 'id': 1}, {'name': 'ps1-saeed11', 'id': 1}, {'name': 'saeed8-gr3', 'id': 1}, ]
需求逻辑
遍历列表项,若名称含gr1且ID相同,输出对应项对; 遍历列表项,若名称含gr2且ID相同,输出对应项对; 遍历列表项,若名称含gr3且ID相同,输出对应项对; 遍历列表项,若名称含pl1且ID相同,输出对应项对; 遍历列表项,若名称含ps1且ID相同,输出对应项对;
尝试代码
tmp = [] for name1 in list1: for name2 in list1: if name1['name'] != name2['name'] and name1['id'] == name2['id'] and name1['name'] not in tmp: tmp.append(name1['name']) print(f'equal {name1["name"]} == {name2["name"]} with same id {name1["id"]}')
错误输出
equal saeed1-gr1 == pl1-saeed1 with same id 1 equal pl1-saeed1 == saeed1-gr1 with same id 1 equal saeed11-gr2 == saeed1-gr1 with same id 1 equal saeed3-gr2 == saeed1-gr1 with same id 1 equal pl1-saeed7 == saeed1-gr1 with same id 1 equal saeed15-gr1 == saeed1-gr1 with same id 1 equal ps1-saeed15 == saeed1-gr1 with same id 1 equal ps1-saeed11 == saeed1-gr1 with same id 1 equal saeed8-gr3 == saeed1-gr1 with same id 1
期望输出
names saeed1-gr1 and saeed15-gr1 same id 1 names saeed11-gr2 and saeed3-gr2 same id 8 names pl1-saeed1 and pl1-saeed7 same id 1 names ps1-saeed15 and ps1-saeed11 same id 1
正确实现方案
问题分析
原代码存在三个核心问题:
- 未按分组标识过滤,导致跨组匹配不同标识的项
- 双重循环生成重复配对(如
a和b、b和a都输出) - 临时列表去重逻辑不严谨,无法精准控制分组匹配
解决方案代码
from collections import defaultdict list1 = [ {'name': 'saeed1-gr1', 'id': 1}, {'name': 'pl1-saeed1', 'id': 1}, {'name': 'saeed11-gr2', 'id': 8}, {'name': 'pl1-saeed2', 'id': 2}, {'name': 'saeed3-gr2', 'id': 8}, {'name': 'saeed5-gr1', 'id': 3}, {'name': 'pl1-saeed7', 'id': 1}, {'name': 'saeed15-gr1', 'id': 1}, {'name': 'ps1-saeed15', 'id': 1}, {'name': 'ps1-saeed11', 'id': 1}, {'name': 'saeed8-gr3', 'id': 1}, ] # 定义需要匹配的分组标识 target_groups = ['gr1', 'gr2', 'gr3', 'pl1', 'ps1'] # 用(分组标识,ID)作为键,分组存储对应名称 grouped_items = defaultdict(list) for item in list1: item_name = item['name'] item_id = item['id'] # 匹配当前名称所属的分组 for group in target_groups: if group in item_name: grouped_items[(group, item_id)].append(item_name) break # 一个名称仅属于一个分组,匹配到即停止 # 遍历分组,输出符合条件的项对 for (group, item_id), names in grouped_items.items(): # 仅当组内有至少2个名称时输出配对 if len(names) >= 2: # 生成不重复的两两配对(避免a和b、b和a重复输出) for i in range(len(names)): for j in range(i + 1, len(names)): print(f'names {names[i]} and {names[j]} same id {item_id}')
代码说明
- 分组存储:使用
defaultdict将同分组、同ID的名称归类,确保后续只处理同组内的项 - 精准匹配:遍历每个名称时,仅匹配指定的分组标识,避免跨组错误配对
- 去重输出:通过索引遍历生成两两配对,确保每个配对只输出一次,完全符合期望格式
运行上述代码后,输出将与期望结果完全一致。
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

