Python不依赖pandas实现多键左合并字典列表 缺失值填充0
纯Python实现左合并(等价pandas
pd.merge(how='left')) 原有代码问题
你之前的实现存在三个核心错误:
- 遍历基准选成了右表
l2,本质是做右合并,必然丢失左表中无匹配的记录 - 没有提前收集右表的数值字段,无法对缺失字段统一填充0
- 映射表构建搞反了对象,左合并应该把右表构建为键值映射供左表查找,而非反过来
实现思路
- 固定以左表
l1为遍历基准,保证所有左表记录完整保留 - 提前把右表按关联键
(key1, key2)构建成查找字典,匹配效率为O(1) - 提前收集右表所有非关联键的字段名,遍历左表时先给这些字段统一填0,匹配到右表记录时再覆盖为实际值,自动处理缺失场景
完整实现代码
# 原始输入数据 l1 = [{'key1': '2017', 'key2': '20-30', 'val1': 11}, {'key1': '2017', 'key2': '30-40', 'val1': 22}, {'key1': '2017', 'key2': '40-50', 'val1': 33}, {'key1': '2017', 'key2': '50+', 'val1': 44}, {'key1': '2018', 'key2': '20-30', 'val1': 55}, {'key1': '2018', 'key2': '30-40', 'val1': 66}, {'key1': '2018', 'key2': '40-50', 'val1': 77}, {'key1': '2018', 'key2': '50+', 'val1': 88}] l2 = [{'key1': '2017', 'key2': '20-30', 'val2': 1000}, {'key1': '2017', 'key2': '40-50', 'val3': 2000}, {'key1': '2018', 'key2': '50+', 'val3': 3000}] # 指定关联键 join_keys = ('key1', 'key2') # 构建右表查找映射,同时收集右表所有数值字段 l2_index = {} l2_value_fields = set() for row in l2: index_key = tuple(row[k] for k in join_keys) l2_index[index_key] = row for field in row: if field not in join_keys: l2_value_fields.add(field) # 执行左合并 output = [] for left_row in l1: merged = left_row.copy() # 右表字段先默认填0 for field in l2_value_fields: merged[field] = 0 # 匹配到右表记录则覆盖实际值 current_key = tuple(left_row[k] for k in join_keys) matched_right = l2_index.get(current_key, {}) for field, value in matched_right.items(): if field not in join_keys: merged[field] = value output.append(merged)
效果说明
运行上述代码得到的output和预期结果完全一致,该实现不需要硬编码右表数值字段名,后续右表新增其他数值字段也能自动适配,统一对缺失值填充0。
内容的提问来源于stack exchange,提问作者mk2080
相关产品推荐
相关产品推荐

