Search code examples
pythonjsondictionarynesteddel

Python remove JSON properties in nested JSON data (or dict)


I have some nested JSON data structure like this:

my_dict = {
    "audits": [
        {
            "id": 1,
            "author_id": 15,
            "events": [
                {
                    "id": 307,
                    "type": "Comment",
                    "body": "*Ticket #25*",
                    "plain_body": "Ticket #25",
                    "public": False,
                    "attachments": [],
                    "audit_id":1
                },
                {
                    "id": 308,
                    "type": "Change",
                    "value": "solved",
                    "field_name": "status",
                    "previous_value": "open"
                }
            ],
            "ticket_id": 25
        }
    ]
}

The audits list can have many elements and and each audit can have many "events". I want to remove the "body" and "plain_body" properties from every "event" if they are present, before proceeding with processing it further. I tried to loop over it and delete if I found the keys:

for k1 in my_dict.keys():
    i = 0
    for l2 in my_dict[k1]:
        for l3 in l2.keys():
            if l3 == 'events':
                j = 0
                for l4 in my_dict[k1][i][l3]:
                    for l5 in l4.keys():
                        if l5 in ('body', 'plain_body'):
                            print("Found key to delete: '{0}'".format(l5))
                            print(my_dict[k1][i][l3][j][l5])
                            # del my_dict[k1][i][l3][j][l5]
        i += 1

Apart from the fact that this approach to dig through the data structure seems not pythonic at all, I can't delete from a dict while I'm iterating over it:

RuntimeError: dictionary changed size during iteration

Can anyone provide a pythonic way to browse through the JSON and remove the undesired properties? I have found solutions for this with simple non-hierarchical dicts, but with nested ones.


Solution

  • Instead of iterating everything, go directly, so you will not have the RuntimeError:

    for audit in my_dict["audits"]:
        for event in audit["events"]:
            if "plain_body" in event:
                del event["plain_body"]
            if "body" in event:
                del event["body"]