Home > Software design >  best way to remove nested key with in dictionary
best way to remove nested key with in dictionary

Time:01-09

I have a dictionary something like this so

acc = ["key1", "key_", "four"]

dict = {"key1": "something", "key_": "something2", "three": {"four": "remove this", "five": "dsadsdsas"}}

Need to remove all this particular key from json which is mentioned in acc variable.

{key: value for key, value in dict.items() if key not in acc}

this doesn't remove the "four" key

So what can I do here?

CodePudding user response:

The reason that it does not work like you would is that the keys in your dictionary are: key1, key_ and three. three is not in acc and the value of three is kept. That this value is a dictionary is not tested and therefore not used when you filter your dictionary.

Therefore you have to use recursion to check if the item in your dictionary is itself a dictionary. If that is the case, also filter this "dictionary inside a dictionary".

For example:

# do not use dict, this is a built-in function.
# https://docs.python.org/3/library/functions.html
d = {"key1": "something", "key_": "something2", "three": {"four": "remove this", "five": "dsadsdsas"}}

def filter_dict(d: dict, acc: list = ["key1", "key_", "four"]) -> dict:
    new_d = {}
    for key, value in d.items():
        if key in acc:
            continue
        if isinstance(value, dict):
            new_d[key] = filter_dict(value)
        else:
            new_d[key] = value
    return new_d

filter_dict(d)

>>> {'three': {'five': 'dsadsdsas'}}

This example will return an empty dictionary when all keys are inside acc. How to deal with those kind of dictionaries is up to you, you can change this line to deal with empty dictionaries:

new_d[key] = filter_dict(value)

CodePudding user response:

Simple trick with json.loads and its object_pairs_hook (used on decoding phase):

import json

stop_k = ["key1", "key_", "four"]
d = {"key1": "something", "key_": "something2", "three": {"four": "remove this", "five": "dsadsdsas"}}
filtered = json.loads(json.dumps(d), object_pairs_hook=lambda pairs, stop_k=stop_k: \
    dict((k,v) for k, v in pairs if k not in stop_k))

{'three': {'five': 'dsadsdsas'}}
  • Related