1

In this given dictionary defaultdict(dict) type data:

Say this is the dict1

{726: {'X': [3.5, 3.5, 2.0], 'Y': [2.0, 0.0, 0.0], 'chr': [2, 2, 2]}, 128: {'X': [0.5, 4.0, 4.0], 'Y': [4.0, 3.5, 3.5], 'chr': [3, 3, 3]}}

dict2 is

{726: {'sum_X': [8, 0, 2], 'sum_Y': [3, 2, 0]}, 128: {'sum_X': [0.5, 2, 0], 'sum_Y': [5, 3.5, 3]}}

Expected output:

Union_dict =

{726: {'X': [3.5, 3.5, 2.0], 'Y': [2.0, 0.0, 0.0], 'chr': [2, 2, 2], 'sum_X': [8, 0, 2], 'sum_Y': [3, 2, 0]}, 128: {'X': [0.5, 4.0, 4.0], 'Y': [4.0, 3.5, 3.5], 'chr': [3, 3, 3], 'sum_X': [0.5, 2, 0], 'sum_Y': [5, 3.5, 3]}}

Each dict has a unique key (i.e 726, 128...) and are found in both dictionaries (dict1 and dict2) but each key in different dictionaries have unique identifier with list values. I want to merge these dictionaries using the unique keys, but also want to keep the order of the values inside the list intact and ordered.

I have tried several methods including the extensive method in How to merge two dictionaries in a single expression? explained by Aaron Hall. I tried to modify the approaches using what I know about dict comprehension but its failing.

I tried:

  • 1

    union_dict = {k: [dict1[i] for i in v] for k, v in dict2.items()}
    
  • 2

    union_dict = defaultdict(dict)
    for a,b in dict1.items(), dict2.items():
        union_dict[dict1].append(dict2)
    
  • 3

    dicts = [dict1, dict2]
    union_dict = defaultdict(dict)
    for a,b in dicts:
        union_dict[k] = tuple(union_dict[k] for d in dicts)
    

Also, can you give me a comprehensive explanation of several ways to do it and keep the memory footprint low, since my dictionaries are going to be quite big.

Thanks much !

everestial007
  • 6,665
  • 7
  • 32
  • 72
  • 1
    `[8, 0, 2}`, is that a typo? – Elmex80s Mar 14 '17 at 20:22
  • @Elmex80s: yes it is. its supposed to be `[8, 0, 2]`. – everestial007 Mar 14 '17 at 20:30
  • @TemporalWolf: Sorry if that bothered you. but, I always try to workout the problem myself using what I know, cookbook and old answers on **Stack Overflow**. And, resort to help when the workout deems futile. I hope you understand. Thanks ! – everestial007 Mar 14 '17 at 20:32
  • Actually, nothing for my example. These are only `unique identifier` which hold `list values` within the unique `keys`. The keys are same between two dicts but unique identifier arenot. All, I want is the `union using the keys` nothing else, but preserving the order of the list values. – everestial007 Mar 14 '17 at 20:38
  • Based on what I have read, the `update method` should be working but isn't unless I am not understanding it. – everestial007 Mar 14 '17 at 20:40
  • is it guaranteed that no specific key will be in both dicts? – TemporalWolf Mar 14 '17 at 20:41
  • **keys** will be in both the dictionary but **unique identifier** of the **lists** won't. – everestial007 Mar 14 '17 at 20:43
  • Can you please remove the close flag if anyone did so? It needs one more votes to be closed and I don't want to go through another issue of not having answer or reposting it again. – everestial007 Mar 14 '17 at 20:44

1 Answers1

1

Note: This solution returns the result as dict1:

for key, value in dict2.items():
    for subkey, subvalue in value.items():
        dict1[key][subkey] = subvalue

by appending all subkeys to dict1. If there are conflicts (matching subkeys, dict1s will be overwritten by dict2.

>>> dict1
{128: {'Y': [4.0, 3.5, 3.5], 'X': [0.5, 4.0, 4.0], 'chr': [3, 3, 3], 'sum_Y': [5, 3.5, 3], 'sum_X': [0.5, 2, 0]}, 
 726: {'Y': [2.0, 0.0, 0.0], 'X': [3.5, 3.5, 2.0], 'chr': [2, 2, 2], 'sum_Y': [3, 2, 0], 'sum_X': [8, 0, 2]}}

If you want to preserve dict1, just use copy.deepcopy() and then add to that new dict.

TemporalWolf
  • 7,727
  • 1
  • 30
  • 50