I have two dictionaries as follows, I need to extract values that are in one dictionary but not in other, I have been trying many ways but I am unable to solve this problem.
dict_a = {"s": ("mmmm", "iiiii", "p11"), "yyzz": ("oo", "i9")}
dict_b = {"s": ("mmmm",), "h": ("pp",), "g": ("rr",)}
desired output:
{"s": ("iiiii", "p11"), "yyzz": ("oo", "i9")}
The order doesn't matter.
One way that I tried to solve, but it doesn't produce the expected result:
>>> [item for item in dict_a.values() if item not in dict_b.values()]
[('mmmm', 'iiiii', 'p11'), ('oo', 'i9')]
CodePudding user response:
If order doesn't matter, convert your dictionary values to sets, and subtract these:
{k: set(v) - set(dict_b.get(k, ())) for k, v in dict_a.items()}
The above takes all key-value pairs from dict_a
, and for each such pair, outputs a new dictionary with those keys and a new value that's the set difference between the original value and the corresponding value from dict_b
, if there is one:
>>> dict_a = {"s": ("mmmm", "iiiii", "p11"), "yyzz": ("oo", "i9")}
>>> dict_b = {"s": ("mmmm",), "h": ("pp",), "g": ("rr",)}
>>> {k: set(v) - set(dict_b.get(k, ())) for k, v in dict_a.items()}
{'s': {'p11', 'iiiii'}, 'yyzz': {'oo', 'i9'}}
The output will have sets, but these can be converted back to tuples if necessary:
{k: tuple(set(v) - set(dict_b.get(k, ()))) for k, v in dict_a.items()}
The dict_b.get(k, ())
call ensures there is always a tuple to give to set()
.
If you use the set.difference()
method you don't even need to turn the dict_b
value to a set:
{k: tuple(set(v).difference(dict_b.get(k, ()))) for k, v in dict_a.items()}
CodePudding user response:
Try this (see comments for explanations):
>>> out = {} # Initialise output dictionary
>>> for k, v in dict_a.items(): # Iterate through items of dict_a
... if k not in dict_b: # Check if the key is not in dict_b
... out[k] = v # If it isn't, add to out
... else: # Otherwise
... out[k] = set(v) - set(dict_b[k]) # Subtract sets to find the difference
...
>>> out
{'s': {'iiiii', 'p11'}, 'yyzz': ('oo', 'i9')}
CodePudding user response:
{k: [v for v in vs if v not in dict_b.get(k, [])] for k,vs in dict_a.items()}
if you want to use tuples (or sets - just replace the cast)
{k: tuple(v for v in vs if v not in dict_b.get(k, [])) for k,vs in dict_a.items()}