Python字典扁平化优化:仅在键不唯一时添加父键
解决方案:仅在键重复时添加父键的字典扁平化
这个需求确实很贴合实际场景——常规的递归扁平化会给所有嵌套键都加上父键前缀,但我们往往只需要在键存在重复时才这么做。要实现这个功能,核心思路是先全局统计所有键的出现次数,再在递归扁平化时根据次数决定是否拼接父键。
实现步骤
- 首先遍历整个嵌套字典,统计每个键的出现频率,明确哪些键是重复的。
- 然后进行递归扁平化:遇到频率大于1的键时拼接父键前缀;频率为1的键直接使用原键名。
完整代码
def count_keys(item): """递归统计嵌套字典中所有键的出现次数""" counts = {} def _count(sub_item): if isinstance(sub_item, dict): for key, val in sub_item.items(): counts[key] = counts.get(key, 0) + 1 _count(val) _count(item) return counts def flatten_dict(item, parent_key='', sep='_', counts=None): """仅在键重复时添加父键的扁平化函数""" # 第一次调用时初始化全局键计数 if counts is None: counts = count_keys(item) final = [] for key, val in item.items(): # 只有键重复时,才拼接父键前缀 if counts[key] > 1: new_key = f"{parent_key}{sep}{key}" if parent_key else key else: new_key = key if isinstance(val, dict): # 递归处理嵌套字典:仅当前键是重复键时,才传递父键给下一层 child_parent_key = new_key if counts[key]>1 else '' final.extend(flatten_dict(val, parent_key=child_parent_key, sep=sep, counts=counts).items()) else: final.append((new_key, val)) return dict(final)
代码解释
count_keys函数:通过递归遍历整个嵌套字典,用字典记录每个键的出现次数。比如你的示例{'a':1, 'b': {'a': 1, 'c': 1}},它会返回{'a':2, 'c':1}。flatten_dict函数:- 第一次调用时自动触发
count_keys获取全局键计数,避免重复统计。 - 遍历键值对时,根据键的出现次数决定是否拼接父键:重复键保留父键前缀逻辑,唯一键直接用原键名。
- 递归处理嵌套时,只有当前键是重复键才传递父键,避免给唯一键的子键添加不必要的前缀。
- 第一次调用时自动触发
测试你的示例
test_dict = {'a':1, 'b': {'a': 1, 'c': 1}} print(flatten_dict(test_dict))
输出结果:
{'a': 1, 'b_a': 1, 'c': 1}
完全符合你的预期!
额外测试场景
如果有更深层次的嵌套:
test_dict2 = {'a':1, 'b': {'a': 2, 'c': {'d':3, 'a':4}}} print(flatten_dict(test_dict2))
输出:
{'a': 1, 'b_a': 2, 'd': 3, 'b_c_a': 4}
这里a出现3次,所有嵌套里的a都添加了父键;d是唯一键,直接保留原键名。
内容的提问来源于stack exchange,提问作者slevin886
相关产品推荐
相关产品推荐

