Python 两个字典(dic)中相同key合并(value分别作合成后字典key和value)

要将两个字典中相同的键合并,并将它们的值分别作为合成后字典的键和值,本文主要介绍Python合并两个拥有相同key的字典,根据字典的key做关联,两个字典的value分别做合成后的字典的key和value,示例代码如下:
d = { 94111: {'a': 5,  'b': 7,  'd': 7}, 
95413: {'a': 6, 'd': 4},
84131: {'a': 5, 'b': 15, 'c': 10, 'd': 11},
73173: {'a': 15, 'c': 10, 'd': 15},
80132: {'b': 7, 'c': 7, 'd': 7} }
states = {94111: "TX", 84131: "TX", 95413: "AL", 73173: "AL", 80132: "AL"}

合成后的字典

{'TX': {'a': 10, 'b': 22, 'd': 18, 'c': 10}, 'AL': {'a': 21, 'd': 26, 'c': 17, 'b': 7}}

1、使用collections实现

Python 的 collections 模块 提供了多种专用的容器数据类型,这些数据类型是对 Python 内置的 listdictsettuple 的补充,为我们提供了更灵活、更强大的数据结构。

from collections import defaultdict, Counter

# 字典 d,存储了邮政编码对应的字母计数
d = {
    94111: {'a': 5,  'b': 7,  'd': 7}, 
    95413: {'a': 6,  'd': 4}, 
    84131: {'a': 5,  'b': 15, 'c': 10, 'd': 11}, 
    73173: {'a': 15, 'c': 10, 'd': 15}, 
    80132: {'b': 7,  'c': 7,  'd': 7}
}

# 字典 states,存储了邮政编码对应的州
states = {
    94111: "TX", 
    84131: "TX", 
    95413: "AL", 
    73173: "AL", 
    80132: "AL"
}

# 使用 defaultdict 初始化结果字典,默认值为 Counter 对象
result = defaultdict(Counter)

# 遍历字典 d 的每个键值对for k, v in d.items():
    # 检查邮政编码是否存在于 states 字典中if k in states:
        # 使用邮政编码对应的州作为键,累加该州下的字母计数
        result[states[k]] += Counter(v)

# 输出结果,result 是一个以州为键的字典,值为累加后的 Counter 对象print(result)

输出:

defaultdict(<class 'collections.Counter'>, {'AL': Counter({'d': 26, 'a': 21, 'c': 17, 'b': 7}),
'TX': Counter({'b': 22, 'd': 18, 'a': 10, 'c': 10})})

2、使用字典推导和for循环实现

字典推导式是一种简洁而强大的语法,可以用来快速创建字典。它提供了一种紧凑的方式来生成新的字典,而不需要显式地使用循环和字典构造函数。

# 字典 d 包含一些 ZIP code 作为键,对应的值是另一个字典,
# 其中存储了与该 ZIP code 相关的各种数据,
# 如 'a', 'b', 'c', 'd' 的值
d = {
    94111: {'a': 5,  'b': 7,  'd': 7},
    95413: {'a': 6,  'd': 4},
    84131: {'a': 5,  'b': 15, 'c': 10, 'd': 11},
    73173: {'a': 15, 'c': 10, 'd': 15},
    80132: {'b': 7,  'c': 7,  'd': 7}
}

# 字典 states 将 ZIP code 映射到州(state)的缩写
states = {
    94111: "TX",
    84131: "TX",
    95413: "AL",
    73173: "AL",
    80132: "AL"
}

# 初始化结果字典 out,将各州的缩写作为键,初始值为 0
out = {i: 0 for i in states.values()}

# 遍历字典 d 的所有键值对
for key, value in d.items():
    # 检查当前 ZIP code 是否在 states 字典中
    if key in states:
        # 如果 out 中该州的值还未设置(为 0),
        # 则直接将该 ZIP code 的数据赋值给 out 中对应的州
        if not out[states[key]]:
            out[states[key]] = value
        else:
            # 否则,将该 ZIP code 的数据与已有的州数据合并
            for k, v in value.items():
                # 如果 out 中该州已经有相应的键,则累加值
                if k in out[states[key]]:
                    out[states[key]][k] += v
                # 如果没有相应的键,则添加该键值对
                else:
                    out[states[key]][k] = v

# 打印最终合并后的结果
print(out)
# 预期输出 -> {'TX': {'a': 10, 'b': 22, 'd': 18, 'c': 10}, 
#'AL': {'a': 21, 'd': 26, 'c': 17, 'b': 7}}
推荐阅读
cjavapy编程之路首页