简体   繁体   中英

Merge values of a dictionary by key based on custom function

Assume you have two dictionaries and you want to merge the two dictionaries by applying a function to the values that have matching keys. here I use the + operator as binary function.

x = { 1: "a", 2: "b", 3: "c" }
y = { 1: "A", 2: "B", 3: "C" }

result = { t[0][0]: t[0][1] + t[1][1] for t in zip(sorted(x.items()), sorted(y.items())) }

print result # gives { 1: "aA", 2: "bB", 3: "cC" }

I would prefer a self contained expression instead of statements, but this is unreadable.

so far I'm doing:

def dzip(f, a, b):
    least_keys = set.intersection(set(a.keys()), set(b.keys()))
    copy_dict = dict()
    for i in least_keys.keys():
        copy_dict[i] = f(a[i], b[i])
    return copy_dict

print dzip(lambda a,b: a+b,x,y)

Is there a more readable solution to this than the expression I gave?

In the first case, you can directly use a dict comprehension:

>>> x = { 1: "a", 2: "b", 3: "c" }
>>> y = { 1: "A", 2: "B", 3: "C" }
>>> {key: x.get(key, "") + y.get(key, "") for key in set.intersection(set(x.keys()), set(y.keys()))}
{1: 'aA', 2: 'bB', 3: 'cC'}

So that in your second piece of code, you can simplify it to a simple one liner:

def dzip(f, a, b):
    return {key: f(a.get(key, ""), b.get(key, "")) for key in set.inersection(set(a.keys()) + set(b.keys()))}

You can even define dzip as a lambda:

dzip = lambda f, a, b: {key: f(a.get(key, ""), b.get(key, "")) 
    for key in set.intersection(set(a.keys()), set(b.keys()))}

In a single run, this becomes:

>>> dzip = lambda f, a, b: {key: f(a.get(key, ""), b.get(key, "")) 
...         for key in set.intersection(set(a.keys()), set(b.keys()))}    
>>> 
>>> print dzip(lambda a,b: a+b,x,y)
{1: 'aA', 2: 'bB', 3: 'cC'}

Note that this will work even if x and y have different sets of keys (just something that can break in your first version of the code).

You can use Counter for this type of dict merging

from collections import Counter
>>>Counter(x)+Counter(y)
Counter({3: 'cC', 2: 'bB', 1: 'aA'})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM