Home > Software engineering >  How to check if values inside a nested dictionary are equals
How to check if values inside a nested dictionary are equals

Time:11-03

Maybe a dummy question ,but I'm a little bit stuck with my code

I've got a dictionary like that

{'k1': {'a': 11111,
        'aa': 11111,
        'b': 11111,
        'bb': 11111,
        'c': 11111,
        'cc': 11111,
        'd': 22222,
        'dd': 22223,
        'ee': 22222},
 'k2': {'f': 33333,
        'g': 33333,
        'h': 33333,
        'i': 33333,
        'j': 33333,
        'k': 44443,
        'l': 33334,
        'm': 44443,
        'n': 44443}}

and I want to get the value/s that's different from others in every pairs of keys (assuming that more than half will be equal values.)

i.e in the above example K1[d],K1[dd] and K1[ee] values are different from K1[a],K1[b],K1[c],K1[bb],K1[cc] idem for K2


for k,v in my_dict.items():
   if isinstance(v,dict):
      for key,value in v.items():
         print(k,value) <-- dunno how to check differences on the fly

CodePudding user response:

You can use set on the dict values and see if its len is 1:

{k: len(set(v.values())) == 1 for k, v in d.items()}

Result:

{'k1': False, 'k2': True}

CodePudding user response:

If you want to check if all values are equal, one approach is to do:

d = {'k1': {'a': 11111,
            'b': 11111,
            'c': 11111,
            'd': 22222},
     'k2': {'f': 33333,
            'g': 33333,
            'h': 33333,
            'i': 33333}}

for k, dic in d.items():
    iterable = iter(dic.values())
    first = next(iterable)
    all_equals = all(first == val for val in iterable)
    print(k, all_equals)

Output

k1 False
k2 True

As an alternative, if the elements are hashable, you could use a set to find the number of unique elements and verify if this number is 1:

for k, dic in d.items():
    print(k, 1 == len(set(dic.values())))

Output

k1 False
k2 True

UPDATE

If the number of internal keys are 10, and there are always 6 equals elements, you could do:

d = {'k1': {'a': 11111,
            'aa': 11111,
            'b': 11111,
            'bb': 11111,
            'c': 11111,
            'cc': 11111,
            'd': 22222,
            'dd': 22223,
            'ee': 22222},
     'k2': {'f': 33333,
            'g': 33333,
            'h': 33333,
            'i': 33333,
            'j': 33333,
            'jj': 33333,
            'k': 44443,
            'l': 33334,
            'm': 44443,
            'n': 44443}}

for k, dic in d.items():
    inverse = {}
    for ki, val in dic.items():
        if val not in inverse:
            inverse[val] = []
        inverse[val].append(ki)
    for val, kis in inverse.items():
        if len(kis) < 6:
            print(k, val, kis)

Output

k1 22222 ['d', 'ee']
k1 22223 ['dd']
k2 44443 ['k', 'm', 'n']
k2 33334 ['l']

The output above gives the top key, the value and the corresponding internal keys.

CodePudding user response:

You could use the Counter class (from collection) to identify the most common value in each sub-dictionary and the use that as a filter on the keys:

from collections import Counter

common = {k:Counter(d.values()).most_common(1)[0][0] for k,d in K.items()}
r = { k:{kn for kn,v in d.items() if common[k]!=v} for k,d in K.items() }

print(r)
{'k1': {'dd', 'ee', 'd'}, 'k2': {'k', 'n', 'm', 'l'}}
  • Related