Trick
The trick is to find out in advance whether a target_key is among the next children (= this_dict[key]
= the values of the current dict iteration) before you reach the child level recursively. Only then you can still delete a key:value pair of the child level while iterating over a dictionary. Once you have reached the same level as the key to be deleted and then try to delete it from there, you get the error:
RuntimeError: dictionary changed size during iteration
Code
Thus, the code looks as follows:
import copy
def find_remove(this_dict, target_key, bln_overwrite_dict=False):
if not bln_overwrite_dict:
this_dict = copy.deepcopy(this_dict)
for key in this_dict:
# if the current value is a dict, dive into it
if isinstance(this_dict[key], dict):
if target_key in this_dict[key]:
this_dict[key].pop(target_key)
this_dict[key] = find_remove(this_dict[key], target_key)
return this_dict
dict_nested_new = find_remove(nested_dict, "sub_key2a")
Credits
This is almost a copy of the spin-off How can I replace a key:value pair by its value wherever the chosen key occurs in a deeply nested dictionary?. But it took me a while to change that answer so that it would delete a key:value by its key. That is why I am sharing this, please mind that 95% of the credits go to the link!
The main added value over the “spun-off answer” is that you search for the target_key
in the values in advance of entering the next recursion level by checking if target_key in this_dict[key]:
.
Side note: Formatting the output
If you want to print or save the dictionary nicely, see How do I write JSON data to a file?.
solved How can I remove a key:value pair wherever the chosen key occurs in a deeply nested dictionary? [duplicate]