Home > Back-end >  Extract differences of values of 2 given dictionaries- values are in tuple
Extract differences of values of 2 given dictionaries- values are in tuple

Time:08-19

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()}
  • Related