简体   繁体   中英

Delete dictionary element based on a value in a nested dictionary in a list

I am trying to remove an element in a nested dictionary with in a list. Hence, I have a list, which has a dictionary as one of its elements, which then in turn has a dictionary as one of its key values. I know the keys I am going to use in the top-most list and bottom-most dictionary , while the key in the "middle" dictionary is variable. If a value in the bottom dictionary is not equal to a certain value, I want to delete the element in the "middle" dictionary.

I figured I would need three nested for loops to get into each dictionary but have not been able to figure out how to remove the element in the "middle" dictionary.

My current attempt so far:

#remove unneccessary elements
def getCleanResults(the_dict1):
    for elem1 in the_dict1:
        the_dict2 = elem['dict1_key']
        for key, elem2 in the_dict2.keys():
            the_dict3 = elem2[key]
            for elem3 in the_dict3:
                if 'keyWanted' in elem3:
                    del elem2
    return the_dict

The template of the list of dictionaries I have:

a = {
        {'key1':{'key1.1': {'delete': True, 'result': None},
        'key1.2': {'delete': False, 'result': None}},'key2': 3},
        {'key1':{'key1.1': {'delete': False, 'result': None},
        'key1.2': {'delete': True, 'result': None}},'key2': 5}
}

I want to remove the keys keyx.x that have under them a 'delete' that is True , which would, as per the example above, yield:

a = {
    {'key1':{'key1.2': {'delete': False, 'result': None}},'key2': 3},
    {'key1':{'key1.1': {'delete': False, 'result': None}},'key2': 5}
}

As seen in the example above, they removed keys are key1.1 and key1.2 and hence are variable.

I guess, your struggle comes from the python restriction to modifying the dictionary during iteration. To make what you want, you need to make a copy of your dict — either make copy, iterate over, and delete keys from original one; or iterate over original one and put "filtered" keys into new. Later can be done with

b = {k1: {k2: v2 for k2, v2 in v1.items() if not v2['delete']}
     for k1, v1 in a.items()}

EDIT: for some reason, there's no consistency in code you've provided, solution above is assuming that structures is actually

a = {'key1.1': {'key1.1.1': {'delete': True, 'loremipsum': 'perhaps'},
                'key1.1.2': {'delete': False, 'loremipsum': 'perhaps'}},
     'key1.2': {'key1.2.1': {'delete': False, 'loremipsum': 'perhaps'},
                'key1.2.2': {'delete': False, 'loremipsum': 'perhaps'}},
     'key2.1': {'key2.1.1': {'delete': False, 'loremipsum': 'perhaps'},
                'key2.1.2': {'delete': False, 'loremipsum': 'perhaps'}},
     'key2.2': {'key2.2.1': {'delete': False, 'loremipsum': 'perhaps'},
                'key2.2.2': {'delete': True, 'loremipsum': 'perhaps'}}
}

b = {'key1.1': {'key1.1.2': {'delete': False, 'loremipsum': 'perhaps'}},
     'key1.2': {'key1.2.1': {'delete': False, 'loremipsum': 'perhaps'},
                'key1.2.2': {'delete': False, 'loremipsum': 'perhaps'}},
     'key2.1': {'key2.1.1': {'delete': False, 'loremipsum': 'perhaps'},
                'key2.1.2': {'delete': False, 'loremipsum': 'perhaps'}},
     'key2.2': {'key2.2.1': {'delete': False, 'loremipsum': 'perhaps'}}
}

If you use the correct syntax for dictionary a , you can iterate through the first tier keys, then like you said, do a nested loop to iterate through the second tier keys. The VALUE from the_dict1[key1][key2] is the final dictionary. I used pprint to help visualize the dictionary.

def getCleanResults(the_dict1):
    # iterate through the first keys, cast as a tuple to make a copy of the keys iterator (allows for changing dictionary size during iteration)
    for key1 in tuple(the_dict1.keys()):
        the_dict2 = the_dict1[key1]
        # iterate through the second tier keys
        for key2 in tuple(the_dict2.keys()):
            if the_dict1[key1][key2]['delete']:
                del the_dict1[key1][key2]
    # no need to return a new dict, it was passed by reference, we modified the original dict. If you wanted a copy of the dict, make copy and return it instead.

Dictionary in the correct format:

a = {
    'key1.1': {'key1.1.1': {'delete': True, 'loremipsum': 'perhaps'},
                'key1.1.2': {'delete': False, 'loremipsum': 'perhaps'}},
    'key1.2': {'key1.2.1': {'delete': False, 'loremipsum': 'perhaps'},
            'key1.2.2': {'delete': False, 'loremipsum': 'perhaps'}},
    'key2.1': {'key2.1.1': {'delete': False, 'loremipsum': 'perhaps'},
            'key2.1.2': {'delete': False, 'loremipsum': 'perhaps'}},
    'key2.2': {'key2.2.1': {'delete': False, 'loremipsum': 'perhaps'},
            'key2.2.2': {'delete': True, 'loremipsum': 'perhaps'}}
}

Testing:

from pprint import pprint

getCleanResults(a)
print()
pprint(a)

Output:

{'key1.1': {'key1.1.2': {'delete': False, 'loremipsum': 'perhaps'}},
 'key1.2': {'key1.2.1': {'delete': False, 'loremipsum': 'perhaps'},
            'key1.2.2': {'delete': False, 'loremipsum': 'perhaps'}},
 'key2.1': {'key2.1.1': {'delete': False, 'loremipsum': 'perhaps'},
            'key2.1.2': {'delete': False, 'loremipsum': 'perhaps'}},
 'key2.2': {'key2.2.1': {'delete': False, 'loremipsum': 'perhaps'}}}

You can try like this.

Code snippet

import json

def delete_items(d):
    keys1 = d.keys()
    new_d = {}

    for key1 in keys1:
        keys2 = d[key1].keys();
        for key2 in keys2:
            if type(d[key1][key2]) is dict:
                if d[key1][key2]["delete"] == False:
                    if key1 in new_d:
                        new_d[key1][key2] = d[key1][key2]
                    else:
                        new_d[key1] = {key2: d[key1][key2]}
            else:
                if key1 in d:
                    new_d[key1] = {key2: d[key1][key2]}
                else:
                    new_d[key1][key2] = d[key1][key2]

    return new_d


a = {
        "key1.1": {
            "key1.1.1": {
                "delete": True,
                "loremipsum": "perhaps"
            },
            "key1.1.2": {
                "delete": False,
                "loremipsum": "perhaps"
            },
            "key1.1.3": 4
        },
        "key1.2": {
            "key1.2.1": {
                "delete": False,
                "loremipsum": "perhaps"
            },
            "key1.2.2": {
                "delete": False,
                "loremipsum": "perhaps"
            }
        },
        "key2.1": {
            "key2.1.1": {
                "delete": False,
                "loremipsum": "perhaps"
            },
            "key2.1.2": {
                "delete": False,
                "loremipsum": "perhaps"
            },
            "key2.1.3": 9
        },
        "key2.2": {
            "key2.2.1": {
                "delete": False,
                "loremipsum": "perhaps"
            },
            "key2.2.2": {
                "delete": True,
                "loremipsum": "perhaps"
            },
            "key2.2.3": 2
        }
    }

d = delete_items(a)
print(json.dumps(d, indent=4))

Output

{
    "key1.2": {
        "key1.2.1": {
            "delete": false,
            "loremipsum": "perhaps"
        },
        "key1.2.2": {
            "delete": false,
            "loremipsum": "perhaps"
        }
    },
    "key1.1": {
        "key1.1.3": 4,
        "key1.1.2": {
            "delete": false,
            "loremipsum": "perhaps"
        }
    },
    "key2.1": {
        "key2.1.3": 9
    },
    "key2.2": {
        "key2.2.3": 2
    }
}

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM