I would like to compare two dictionaries that have list of values as follows:
dict1 = {'111': [], '333': ['a@a.com'], '444': ['b@b.com', 'c@c.com'], '555': ['d@d.com']}
dict2 = {'111': ['e@e.com'], '333': ['f@f.com' ], '444': ['b@b.com', 'g@g.com'], '555': ['d@d.com']}
and create a resultant dict (result_dict) that satisfies the following conditions:
The resultant dict should look as follows:
dict3 = {'1111': ['e@e.com'], '333': ['f@f.com'], '444': ['g@g.com']}
I have the following code
result_dict = {}
for k,v in dict2.items():
for k1,v1 in dict1.items():
if k == k1 and v != v1:
result_dict[k] = v
print(result_dict)
Which outputs:
{'111': ['e@e.com'], '333': ['f@f.com'], '444': ['b@b.com', 'g@g.com']}
In the above case it should not have added 'b@b.com'
for 444. It also gives incorrect result if the order is changed for eg
'444': ['b@b.com', 'c@c.com']
'444': ['c@c.com', 'b@b.com']
Sorting dict values will not help, coz there will be scenarios where dict1 has more values than dict2 for ceratin keys. I am using Python 3.7. Any help would be greatly appreciated
If you want to keep the same order in the result_dict
as in the original dict ( dict2
, I mean):
result_dict = {
k: v if k not in dict1 else [a for a in v if a not in dict1[k]]
for k, v in filter(lambda x: len(set(x[1]).difference(dict1.get(x[0], []))), dict2.items())
}
Here result_dict
:
{'111': ['e@e.com'], '333': ['f@f.com'], '444': ['g@g.com']}
The output dict is created by a dict comprehension . Basically, we select keys in dict2
whose values are lists with at least one original element compared to the correspondent lists in dict1
. Then, lists of the selected keys are cleaned, removing elements also present in the correspondent lists in dict1
. In particular:
filter(lambda x: len(set(x[1]).difference(dict1.get(x[0], []))), dict2.items()) }
: only loop over the pairs key/list of dict2
having at least one element that is not in the correspondent list of dict1
. k: v if k not in dict1 else [a for a in v if a not in dict1[k]]
create an entry in the new dict with the same key of dict2
and as value the corresponding list in dict2
, if the key in not in dict1
, else create a new list (with list comprehension ) looping over the item in the list of dict2
and removing those also in the correspondent list in dict1
(this will preserve the order of the original list in dict2
. You can filter out any of the items who's values match, then within a dict comprehension the new keys should be the set.difference
for the corresponding keys.
>>> {k:list(set(v).difference(dict1[k])) for k,v in dict2.items() if dict1[k] != v}
{'111': ['e@e.com'], '333': ['f@f.com'], '444': ['g@g.com']}
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.