How to find common items across dictionaries where values can be lists

Question:

I have multiple dictionaries of varying size in a list which I want to find common items across.

Some of these dictionaries can have a list of dictionaries as some of the values.

Order does not matter so two sets of dictionary items are common regardless of order of keys. Two lists are common as long as the set of values are equal.

For instance, two dictionaries could look like.

d1 = {'a' : 1 , 'b' : [{'c':1,'d':2},{'e':3,'f':4}]}

d2 = {'a' : 1 , 'b' : [{'c':1,'d':2},{'f':4,'e':3}], 'g':4}

So common items here would be

common = {'a' : 1 , 'b' : [{'c':1,'d':2},{'e':3,'f':4}]}

In the case of.

d1 = {'a' : 1 , 'b' : [{'c':1,'d':2},{'e':3,'f':4}]}

d2 = {'a' : 1 , 'b' : [{'f':4,'e':3},{'c':1,'d':2}], 'g':4}

Since order does not matter, common items here would still be

common = {'a' : 1 , 'b' : [{'c':1,'d':2},{'e':3,'f':4}]}

If the case would be

d1 = {'a' : 1 , 'b' : [{'c':1,'d':2},{'e':3,'f':{'h':5}}]}

d2 = {'a' : 1 , 'b' : [{'c':1,'d':2},{'f':4,'e':3}], 'g':4}

Then common items here would be

common = {'a' : 1}

Since the list of dictionaries are not identical.

In the case a key has a list of dictionaries as value, it is a common value between two dictionaries if the two lists are identical. But I can’t out of the box use a string representation of the list because the order of the keys inside the dictionaries should not matter.

In the case of non list values I would simply do

 def extract_common_values(list_of_dictionaries):
     final_dict_items = list_of_dictionaries[0].items()
     for d in list_of_dictionaries[1:]:
         final_dict_items = final_dict_items & d.items()
return final_dict_items

But in my case now, it throws

    Cell In [12], line 18, in extract_common_values(list_of_dictionaries)
                       16 final_dict_items = list_of_dictionaries[0].items()
                       17 for d in list_of_dictionaries[1:]:
                  ---> 18     final_dict_items = final_dict_items & d.items()
                       19 return final_dict_items

                       TypeError: unhashable type: 'list'

What could be some way to solve this?

Asked By: Kspr

||

Answers:

def extract_common_values(d1, d2):
    common = {}
    for key in d1:
        v1 = d1[key]
        v2 = d2.get(key)
        if isinstance(v1, list) and isinstance(v2, list):
            if all(x in v1 for x in v2) and all(x in v2 for x in v1):
                 common[key] = v1
        elif v1 == v2:
            common[key] = v1
    return common
d1 = {'a' : 1 , 'b' : [{'c':1,'d':2},{'e':3,'f':4}]}
d2 = {'a' : 1 , 'b' : [{'c':1,'d':2},{'f':4,'e':3}], 'g':4}
print(extract_common_values(d1, d2))

# Output:
{'a': 1, 'b': [{'c': 1, 'd': 2}, {'e': 3, 'f': 4}]}
d1 = {'a' : 1 , 'b' : [{'c':1,'d':2},{'e':3,'f':4}]}
d2 = {'a' : 1 , 'b' : [{'f':4,'e':3},{'c':1,'d':2}], 'g':4}
print(extract_common_values(d1, d2))

# Output:
{'a' :{'a': 1, 'b': [{'c': 1, 'd': 2}, {'e': 3, 'f': 4}]}
d1 = {'a' : 1 , 'b' : [{'c':1,'d':2},{'e':3,'f':{'h':5}}]}
d2 = {'a' : 1 , 'b' : [{'c':1,'d':2},{'f':4,'e':3}], 'g':4}
print(extract_common_values(d1, d2))

# Output:
{'a': 1}
Answered By: BeRT2me
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.