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'}}