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?
CodePudding user response:
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}