如何合并Python中n个列表生成笛卡尔积形式的字典列表?
问题描述
现有多个Python列表,每个列表里的元素都是单键字典:
data1 = [{"key1": i} for i in range(331)] data2 = [{"key2": i} for i in range(4)] ... dataN = [{"keyN": i} for i in range(n)]
把这些列表放到一个统一的列表变量 data = [data1, data2, ...., dataN] 里,怎么生成所有字典的笛卡尔积合并结果?最终要得到的格式如下:
[{'key1': 0, 'key2': 0, ...., "keyN" : 0}, {'key1': 0, 'key2': 0, ...., "keyN" : 1}, ... {'key1': 330, 'key2': 3,...., "keyN" : n-1}]
方案1:用itertools.product(最省心高效)
Python标准库的itertools.product专门用来生成多个可迭代对象的笛卡尔积,搭配字典合并就能快速搞定:
import itertools # 示例数据演示 data1 = [{"key1": i} for i in range(331)] data2 = [{"key2": i} for i in range(4)] data3 = [{"key3": i} for i in range(2)] data = [data1, data2, data3] # 生成合并结果 merged_data = [] for item_group in itertools.product(*data): combined_dict = {} for d in item_group: combined_dict.update(d) merged_data.append(combined_dict) # 也可以用一行列表推导式简化 merged_data = [dict(kv for d in group for kv in d.items()) for group in itertools.product(*data)]
原理很直白:itertools.product(*data)会把data里的每个子列表拆成独立参数,生成所有可能的元素组合(每个组合包含每个子列表中的一个字典),再把组合里的所有字典键值对合并成一个新字典即可。
方案2:递归实现(无需依赖标准库)
如果不想用itertools,可以自己写递归逻辑来实现:
def merge_all_dicts(data_list): # 递归终止条件:只剩一个列表时直接返回副本 if len(data_list) == 1: return [d.copy() for d in data_list[0]] # 先处理剩余所有列表的合并结果 rest_merged = merge_all_dicts(data_list[1:]) final_merged = [] # 把当前列表的每个元素和剩余合并结果逐个合并 for d in data_list[0]: for merged_d in rest_merged: final_merged.append({**d, **merged_d}) return final_merged # 调用示例 merged_data = merge_all_dicts(data)
这个思路是把问题拆分成小单元:每次只处理第一个列表和剩下所有列表的合并结果,通过递归逐步完成所有列表的笛卡尔积合并。
额外提示
- 就算子列表里的字典不是单键的也没关系,只要键不冲突,上面的方法都能正常合并;如果有重复键,后面的字典会覆盖前面的(和Python字典解包的规则一致)。
- 如果子列表数量多或者元素量大,用生成器代替列表推导式可以节省内存,避免一次性生成所有结果:
def generate_merged(data): for group in itertools.product(*data): yield dict(kv for d in group for kv in d.items()) # 逐个获取结果,无需一次性占用大量内存 for item in generate_merged(data): print(item)
内容的提问来源于stack exchange,提问作者daa2618
相关产品推荐
相关产品推荐

