Search code examples
python-2.7subsetdefaultdict

Compare dictionaries and delete key:value pairs


I have two list dictionaries.

big_dict = defaultdict(list)
small_dict defaultdict(list)


big_dict = {StepOne:[{PairOne:{key1: value1}}, {PairTwo:{key2: value2}}, {PairThree: {key3: value3}}]}


small_dict = {key1: value1}

Is it possible found subset of second dictionary in 'StepOne' and delete another sub-dictionaries in 'StepOne' key?


Solution

  • I bet there is a more pythonic way to do it, but this should solve your problem:

    big_dict = {'A0':[{'a':{'ab':1}, 'b':{'bb':2}, 'c':{'cc':3}}], 'A1':[{'b':{'bb':1}, 'c':{'bb':5}, 'd':{'cc':3}}]}
    
    small_dict = {'bb':2, 'cc':3}
    
    for big_key in big_dict.keys():
        for nested_key in big_dict[big_key][0].keys():
            ls_small = [ x for x in small_dict if x in big_dict[big_key][0][nested_key]]
            if not ls_small:
                del big_dict[big_key][0][nested_key]
            else:
                ls_small = [ y for y in ls_small if small_dict[y] is big_dict[big_key][0][nested_key][y]]
                if not ls_small:
                    del big_dict[big_key][0][nested_key]
            ls_small = []
    

    I've added another main dictionary, 'A1' to make it more representative. What this does is it loops through keys of the main dictionary ('A0', 'A1') and then through keys of the first set of nested dictionaries ('a', 'b',...). It selects the nested dictionaries as the 1st element of the lists - values of the main dictionaries.

    For each nested dictionary it checks if any of the keys in small_dict are part of it's subdictionary. The sibdictionary is fetched by big_dict[big_key][nested_key] since it's the value of the nested dictionary. If the small_dict keys are found in the subdictionary, they are temporarily stored in ls_small.

    If ls_small for that nested dictionary is empty after key-checking step it means no keys from small_dict are present in that nested dictionary and the nested dictionary is deleted. If it is not empty, the else part checks for matching of the values - again deleting the entry if the values don't match.

    The output for this example is:

    {'A1': [{'d': {'cc': 3}}], 'A0': [{'c': {'cc': 3}, 'b': {'bb': 2}}]}
    

    Note - as it is right now, the approach will keep the nested dictionary if only one small_dict key:value pair matches, meaning that an input of this form

    big_dict = {'A0':[{'a':{'bb':2}, 'b':{'bb':2, 'cc': 5}, 'c':{'cc':3}}], 'A1':[{'b':{'bb':1}, 'c':{'bb':5}, 'd':{'cc':3}}]}
    

    will produce

    {'A1': [{'d': {'cc': 3}}], 'A0': [{'a': {'bb': 2}, 'c': {'cc': 3}, 'b': {'cc': 5, 'bb': 2}}]}
    

    Is this the desired behavior?