如何合并两个字典以保持最大值对公用键?
How do I merge two dictionaries keeping max value against common keys?
我有两个字典,看起来像:
{'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}
None 之前的答案对我有帮助。
您可以使用 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()
你可以创建一个包含两个字典键的并集,然后使用一个为每个键取最大值的字典理解:
keys = set(a.keys()).union(b.keys())
output = {k:max(a.get(k,float('-inf')), b.get(k, float('-inf'))) for k in keys}
我有两个字典,看起来像:
{'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}
None 之前的答案对我有帮助。
您可以使用 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()
你可以创建一个包含两个字典键的并集,然后使用一个为每个键取最大值的字典理解:
keys = set(a.keys()).union(b.keys())
output = {k:max(a.get(k,float('-inf')), b.get(k, float('-inf'))) for k in keys}