【问题标题】:How do I merge two dictionaries keeping max value against common keys?如何合并两个字典以保持公共键的最大值?
【发布时间】:2021-01-14 21:50:55
【问题描述】:

我有两本看起来像这样的字典:

{'r': 2, 'e': 4, 'h': 2, 'k': 4}

{'r': 2, 'e': 5, 'y': 2, 'h': 2}

如何获得一个包含所有键的字典,但如果两个初始字典中都有键,它会为该键保留更高的值? 我想要一个看起来像这样的字典:

{'e': 5, 'k': 4, 'y': 2, 'h': 2, 'r': 2}

以前的答案都没有帮助我。

【问题讨论】:

  • 遍历两个输入字典并更新结果字典。
  • 我正在编写大型词典,有没有更高效的方法?

标签: python dictionary mergeddictionaries


【解决方案1】:

您可以使用itertools.chain 组合所有值,然后使用itertools.groupby 获取每个单独键的所有值,并获取这些值的最大值。您需要在使用 groupby 之前对合并的数据进行排序,以便它正常工作。此外,我使用operator.itemgetter 来获取键和值而不是 lambda,因此如果您不想导入另一个库,则可以将它们替换为 lambda,尽管我不建议这样做,因为它速度较慢且没有真正需要真正使用它们。

from itertools import chain, groupby
from operator import itemgetter

data1 = {'r': 2, 'e': 4, 'h': 2, 'k': 4}
data2 = {'r': 2, 'e': 5, 'y': 2, 'h': 2}

get_key, get_val = itemgetter(0), itemgetter(1)
merged_data = sorted(chain(data1.items(), data2.items()), key=get_key)

output = {k: max(map(get_val, g)) for k, g in groupby(merged_data, key=get_key)}

print(output)

{'e': 5, 'h': 2, 'k': 4, 'r': 2, 'y': 2}

这里的另一种选择是collections.defaultdict,如果有负值,为了确保您始终获得正确的输出,请使用float('-inf')作为默认值:

from collections import defaultdict

output = defaultdict(lambda: float('-inf'))

for d in (data1, data2):
    for k, v in d.items():
        output[k] = max(output[k], v)

print(dict(output))

{'r': 2, 'e': 5, 'h': 2, 'k': 4, 'y': 2}

或者不用任何导入dict.setdefault基本可以代替defaultdict

output = {}

for d in (data1, data2):
    for k, v in d.items():
        output.setdefault(k, float('-inf'))
        output[k] = max(output[k], v)
        
print(output)

{'r': 2, 'e': 5, 'h': 2, 'k': 4, 'y': 2}

最后,使用pandas

import pandas as pd

data1 = {'r': 2, 'e': 4, 'h': 2, 'k': 4}
data2 = {'r': 2, 'e': 5, 'y': 2, 'h': 2}
    
res = pd.concat(map(pd.DataFrame, ([data1], [data2]))).max().astype(int).to_dict()

【讨论】:

    【解决方案2】:

    您可以将两个 dict 键组合成一个联合集,然后使用一个 dict 理解来获取每个键的最大值:

    keys = set(a.keys()).union(b.keys())
    output = {k:max(a.get(k,float('-inf')), b.get(k, float('-inf'))) for k in keys}
    

    【讨论】:

      猜你喜欢
      • 2019-11-11
      • 1970-01-01
      • 2015-04-22
      • 1970-01-01
      • 2020-04-24
      • 2020-11-11
      • 2016-06-20
      • 2023-03-30
      • 1970-01-01
      相关资源
      最近更新 更多