如何以Pythonic方式按list1顺序对三个字典列表按共同值分组?
多字典列表按共同值高效分组实现
问题背景
现有三个字典列表:
list1 = [ {'a': 1, 'fruit': 'apple', 'thing': 'aeroplane'}, {'b': 2, 'fruit': 'banana', 'thing': 'bicycle'}, {'c': 3, 'fruit': 'cherry', 'thing': 'chair'} ] list2 = [ {'fruit': 'apple', 'color': 'green'}, {'fruit': 'banana', 'color': 'yellow'}, {'fruit': 'cherry', 'color': 'red'} ] list3 = [ {'thing': 'aeroplane', 'capacity': 100}, {'thing': 'bicycle', 'capacity': 2}, {'thing': 'chair', 'capacity': 1} ]
需求:将三个列表按共同关联值分组,分组顺序严格遵循list1的顺序,最终得到如下结构:
what_i_want = [ [ {'a': 1, 'fruit': 'apple', 'thing': 'aeroplane'}, {'fruit': 'apple', 'color':'green'}, {'thing': 'aeroplane', 'capacity': 100} ], [ {'b': 2, 'fruit': 'banana', 'thing': 'bicycle'}, {'fruit': 'banana', 'color':'yellow'}, {'thing': 'bicycle', 'capacity': 2} ], [ {'c': 3, 'fruit': 'cherry', 'thing': 'chair'}, {'fruit': 'cherry', 'color': 'red'}, {'thing': 'chair', 'capacity': 1} ] ]
实际场景中各列表包含超100个无序字典,关联值为计算机生成ID,要求实现方式Pythonic且迭代次数最少。
最优解决方案
代码实现
# 构建list2的映射:以fruit为键,对应字典为值 fruit_map = {item['fruit']: item for item in list2} # 构建list3的映射:以thing为键,对应字典为值 thing_map = {item['thing']: item for item in list3} # 按list1的顺序组装分组结果 what_i_want = [ [item, fruit_map[item['fruit']], thing_map[item['thing']]] for item in list1 ]
思路解析
- 预构建映射表:将
list2和list3分别转换成字典映射,把用于关联的字段(示例中为fruit和thing)作为键,对应的字典作为值。这一步仅需遍历list2和list3各一次,时间复杂度为O(m + k)(m、k为两个列表的长度)。 - 按顺序组装分组:直接遍历
list1的每个元素,通过映射表以O(1)的时间复杂度快速找到list2和list3中对应的关联字典,组成分组。这一步遍历list1一次,时间复杂度O(n)。 - 适配实际场景:如果实际用计算机生成ID作为关联键,只需将映射表的键替换为ID字段即可。例如三个列表都有
id字段时,修改映射表为{item['id']: item for item in list2}和{item['id']: item for item in list3},遍历list1时用item['id']去映射表查找。
优势说明
这种方式的总时间复杂度为O(n + m + k),是理论上的最优复杂度,远优于需要排序的groupby方案(排序时间复杂度O(n log n)),且逻辑直观简洁,完全符合Pythonic风格,适合处理大规模无序字典列表的关联分组需求。
内容的提问来源于stack exchange,提问作者FahdS
相关产品推荐
相关产品推荐

