Lukinezko
Lukinezko

Reputation: 89

Python: Merge two dictionaries

Here is my current code:

A = {1 : "one", 2 : "two"}
B = {2 : "dva", 3 : "three"}
d = {}

for key in set(list(A.keys()) + list(B.keys())):
    try:
        d.setdefault(key,[]).append(A[key])
    except KeyError:
        pass

    try:
        d.setdefault(key,[]).append(B[key])
    except KeyError:
        pass
print(d)

And here is the result I'm currently getting:

{1: ['one'], 2: ['two', 'dva'], 3: ['three']}

What do I have to do to get a result that looks like the one below?

{1 : "one", 2 : ["two", "dva"], 3 : "three"}

Upvotes: 5

Views: 9070

Answers (4)

I used dictionaries and groupby groups to find like sets of data. Pandas great for transforming data into dictionaries, tuples, or lists.

A = {1 : "one", 2 : "two"}
B = {2 : "dva", 3 : "three"}

z1=zip(A.keys(),A.values())
z2=zip(B.keys(),B.values())

mylist=[]
mylist.append(list(z1))
mylist.append(list(z2))

variables=[]
phrases=[]
for item in mylist:
   for k,v in item:
       variables.append(k)
       phrases.append(v)
df=pd.DataFrame(zip(variables,phrases),columns=['variable','phrase'])

grpDictionary=df.groupby('variable').groups

resultDictionary={}
for key, values in grpDictionary.items():
    resultDictionary[key]=" ".join(df.iloc[values]['phrase'])

print(resultDictionary)

output:

{1: 'one', 2: 'two dva', 3: 'three'}

Upvotes: 0

Talendar
Talendar

Reputation: 2087

Here's a quick solution:

A = {1 : "one", 2 : "two"}
B = {2 : "dva", 3 : "three"}
d = {**A}

for k, v in B.items():
    d[k] = [d[k], v] if k in d else v

print(d)

Output:

{1: 'one', 2: ['two', 'dva'], 3: 'three'}

Here's a more generalizable solution, that works with an indefinite number of dictionaries:

def cool_dict_merge(dicts_list):
    d = {**dicts_list[0]}
    for entry in dicts_list[1:]:
        for k, v in entry.items():
            d[k] = ([d[k], v] if k in d and type(d[k]) != list
                    else [*d[k], v] if k in d
                    else v)
    return d

Testing:

>>> A = {1: "one", 2: "two"}
>>> B = {2: "dva", 3: "three"}
>>> C = {2: "chewbacca", 3: "ThReE", 4: "four"}
>>> D = {0: "zero", 4: "jack", 5: "five"}
>>> cool_dict_merge([A, B, C, D])
{1: 'one', 2: ['two', 'dva', 'chewbacca'], 3: ['three', 'ThReE'], 4: ['four', 'jack'], 0: 'zero', 5: 'five'}

Note that, as others pointed out, the result you're currently getting is probably more preferable in most scenarios, since it's more generalizable and easier to work with. We don't know about your use case though, so just use the method you feel most comfortable with.

Upvotes: 1

Ilango Rajagopal
Ilango Rajagopal

Reputation: 316

This code achieves what you're looking for:

A = {1 : "one", 2 : "two"}
B = {2 : "dva", 3 : "three"}

d = A.copy()
for key, val in B.items():
    if key in d:
        if isinstance(d[key], list):
            d[key].append(val)
        else:
            d[key] = [d[key], val]
    else:
        d[key] = val

print(d)

But, as mentioned in comments, it is less generalizable, meaning you have to check the type of value everytime (more if-else checks) to work with it.

Upvotes: 0

ddejohn
ddejohn

Reputation: 8962

You could start by first making a new dict using the ** operator:

new_dict = {**A, **B}
>>> new_dict
{1: 'one', 2: 'dva', 3: 'three'}

Then a for loop over the set intersection of keys:

>>> for dupe_key in set(A) & set(B):
...     new_dict[dupe_key] = [A[dupe_key], B[dupe_key]]
...
>>> new_dict
{1: 'one', 2: ['two', 'dva'], 3: 'three'}

Upvotes: 3

Related Questions