合并两个python字典并在新更新的字典中保留最大键val

时间:2019-01-29 12:04:22

标签: python

我需要一种方法,当两个键之一中的值都位于两个字典中时,我可以合并两个字典以保持最大值。

dict_a将“ A”,“ B”,“ C”映射到3、2、6

dict_b将“ B”,“ C”,“ D”映射到7、4、1

final_dict映射“ A”,“ B”,“ C”,“ D”到3、7、6、1

我确实完成了一半的工作,但我不知道如何保持'C'键(值对)的最大值。

用于itertools链()或update()。

6 个答案:

答案 0 :(得分:0)

好的,因此可以通过对所有可能的键dict_a.keys() | dict_b.keys()进行并集,然后使用dict.get来工作,默认情况下,如果键不存在,则返回None(而不是抛出错误) )。然后,我们取{max(不是None的那个)。

def none_max(a, b):
    if a is None:
        return b
    if b is None:
        return a
    return max(a, b)

def max_dict(dict_a, dict_b):
   all_keys = dict_a.keys() | dict_b.keys()
   return  {k: none_max(dict_a.get(k), dict_b.get(k)) for k in all_keys}

请注意,这将适用于任何可比较的值-其他许多答案对于负数或零均失败。


示例: 输入:

dict_a = {'a': 3, 'b': 2, 'c': 6}

dict_b = {'b': 7, 'c': 4, 'd': 1}

输出:

max_dict(dict_a, dict_b)  # == {'b': 7, 'c': 6, 'd': 1, 'a': 3}

答案 1 :(得分:0)

如果您知道所有值都是非负值(或有一个清晰的最小数字),那么此oneliner可以解决您的问题:

a = dict(a=3,b=2,c=6)
b = dict(b=7,c=4,d=1)
merged = { k: max(a.get(k, 0), b.get(k, 0)) for k in set(a) | set(b) }

使用您的最小可能数代替0。 (例如float('-inf')或类似名称。)

答案 2 :(得分:0)

这是一个工作正常的班轮

from itertools import chain

x = dict(a=30,b=40,c=50)
y = dict(a=100,d=10,c=30)

x = {k:max(x.get(k, 0), y.get(k, 0)) for k in set(chain(x,y))}

In[83]: sorted(x.items())
Out[83]: [('a', 100), ('b', 40), ('c', 50), ('d', 10)]

在任何情况下都可以使用,即对于通用键,它将采用值的max,否则将取自相应字典的现有值。

答案 3 :(得分:0)

{
    k:max(
        dict_a.get(k,-float('inf')),
        dict_b.get(k,-float('inf'))
    ) for k in dict_a.keys()|dict_b.keys()
}

返回

{'A': 3, 'D': 1, 'C': 6, 'B': 7}


使用

>>> dict_a = {'A':3, 'B':2, 'C':6}
>>> dict_b = {'B':7, 'C':4, 'D':1}

答案 4 :(得分:0)

另一个解决方案:

a = {"A":3, "B":2, "C":6}
b = {"B":7, "C":4, "D":1}

两个衬里:

b.update({k:max(a[k],b[k]) for k in a if b.get(k,'')})
res = {**a, **b}

或者如果您不想更改b

b_copy = dict(b)
b_copy.update({k:max(a[k],b[k]) for k in a if b.get(k,'')})
res = {**a, **b_copy}

> {'A': 3, 'B': 7, 'C': 6, 'D': 1}

答案 5 :(得分:0)

扩展此功能,以便列表中可以有任意数量的词典,而不仅仅是两个:

a = {'a': 3, 'b': 2, 'c': 6}
b = {'b': 7, 'c': 4, 'd': 1}
c = {'c': 1, 'd': 5, 'e': 7}

all_dicts = [a,b,c]

from functools import reduce

all_keys = reduce((lambda x,y : x | y),[d.keys() for d in all_dicts])

max_dict = { k : max(d.get(k,0) for d in all_dicts) for k in all_keys }