如何获取嵌套字典中对应key下列表的两两交集?
我需要为两个嵌套字典的每个key,计算对应列表的笛卡尔积交集(即第一个字典中key对应的每个子列表,和第二个字典中同key对应的每个子列表分别取交集,按顺序收集结果)。现有两个嵌套字典:
dict_1 = {101: [['14', '02', '03', '07', '11'], ['04', '12', '05', '06', '08'], ['10', '16', '09', '13', '01']], 102: [['21', '19', '14', '07', '10'], ['11', '04', '09', '12', '13'], ['03', '02', '15', '08', '17']] } dict_2 = {101: [['12', '02', '05', '01', '16'], ['04', '03', '18', '10', '14'], ['10', '11', '08', '07', '13']], 102: [['21', '19', '11', '07', '15'], ['08', '03', '09', '12', '13'], ['03', '02', '15', '10', '17']] }
以key=101为例,交集计算规则是:
遍历
dict_1[101]中的每个子列表,分别与dict_2[101]中的每个子列表取交集,按顺序收集所有交集结果:
list_1 = ['14', '02', '03', '07', '11'] 和 ['12', '02', '05', '01', '16'] 的交集
list_2 = ['14', '02', '03', '07', '11'] 和 ['04', '03', '18', '10', '14'] 的交集
list_3 = ['14', '02', '03', '07', '11'] 和 ['10', '11', '08', '07', '13'] 的交集
list_4 = ['04', '12', '05', '06', '08'] 和 ['12', '02', '05', '01', '16'] 的交集
list_5 = ['04', '12', '05', '06', '08'] 和 ['04', '03', '18', '10', '14'] 的交集
list_6 = ['04', '12', '05', '06', '08'] 和 ['10', '11', '08', '07', '13'] 的交集
list_7 = ['10', '16', '09', '13', '01'] 和 ['12', '02', '05', '01', '16'] 的交集
list_8 = ['10', '16', '09', '13', '01'] 和 ['04', '03', '18', '10', '14'] 的交集
list_9 = ['10', '16', '09', '13', '01'] 和 ['10', '11', '08', '07', '13'] 的交集
期望输出格式:
output = {101: [['02'], ['14', '03'], ['07', '11'], ['12', '05'], ['04'], ['08'], ['16', '01'], ['10'], ['10', '13']], 102: [['21', '19', '07'], [], ['10'], ['11'], ['09', '12', '13'], [], ['15'], ['03', '08'], ['03', '02', '15', '17']] }
我能单独计算两个列表的交集,但不知道怎么在嵌套字典中完成整个流程,请问最优实现方法是什么?
核心思路是:遍历两个字典的共同key,对每个key对应的子列表组做笛卡尔积遍历(即第一个列表的每个子列表和第二个列表的每个子列表组合),对每一组组合计算交集,最后按顺序收集结果。
实现代码
def get_nested_intersection(d1, d2): output = {} # 只处理两个字典都存在的key for key in d1.keys() & d2.keys(): group1 = d1[key] group2 = d2[key] intersections = [] # 嵌套循环遍历所有子列表组合 for sublist1 in group1: # 把sublist2转成集合提升查询效率 set_group2 = [set(sublist) for sublist in group2] for s2 in set_group2: # 保留原sublist1的元素顺序 common = [x for x in sublist1 if x in s2] intersections.append(common) output[key] = intersections return output # 测试执行 dict_1 = {101: [['14', '02', '03', '07', '11'], ['04', '12', '05', '06', '08'], ['10', '16', '09', '13', '01']], 102: [['21', '19', '14', '07', '10'], ['11', '04', '09', '12', '13'], ['03', '02', '15', '08', '17']] } dict_2 = {101: [['12', '02', '05', '01', '16'], ['04', '03', '18', '10', '14'], ['10', '11', '08', '07', '13']], 102: [['21', '19', '11', '07', '15'], ['08', '03', '09', '12', '13'], ['03', '02', '15', '10', '17']] } output = get_nested_intersection(dict_1, dict_2) print(output)
关键说明
- 共同key遍历:用
d1.keys() & d2.keys()确保只处理两个字典都存在的key,避免出现KeyError。 - 笛卡尔积组合:通过嵌套循环遍历两组子列表,覆盖所有需要计算交集的组合。
- 高效交集计算:先把
group2的子列表转成集合,再用列表推导式筛选group1子列表中存在于集合的元素,既保证效率,又能保留原列表的元素顺序,和示例输出一致。 - 结果收集:将每对组合的交集按顺序存入列表,最终作为对应key的值存入输出字典。
内容的提问来源于stack exchange,提问作者Masoud180190

