AutoTester213
AutoTester213

Reputation: 2862

Travers through a nested json object and store values- Python

This is a follow up on this question. Question

Also this question is similar but does not solve my problem Question2

I am trying to parse a nested json to get Check how many children a specific location has, I am trying to check if "children:" = None and increment counter to check how many levels down i need to go in order to get the lowest child, or A more efficient solution would be:

I need to get all the child values into a list and keep going until "children:" = None.

The Json object can increase in the amount of children so we can have multiple level of children, Which can get messy if I want to nest the list and get the values, How could I do it dynamically?

{
    'locationId': 'location1',
    'name': 'Name',
    'type': 'Ward',
    'patientId': None,
    'children': [{
        'locationId': 'Child_location2',
        'name': 'Name',
        'type': 'Bed',
        'patientId': None,
        'children': [{
            'locationId': 'Child_Child_location3',
            'name': 'Name',
            'type': 'HospitalGroup',
            'patientId': None,
            'children': None
        }]
    }, {
        'locationId': 'location4',
        'name': 'Name',
        'type': 'Hospital',
        'patientId': None,
        'children': None
    }, {
        'locationId': 'location5',
        'name': 'Name',
        'type': 'Bed',
        'patientId': None,
        'children': None
    }, {
        'locationId': 'location6',
        'name': 'Name',
        'type': 'Bed',
        'patientId': None,
        'children': None
    }, {
        'locationId': 'location27',
        'name': 'Name',
        'type': 'Bed',
        'patientId': None,
        'children': None
    }]
}

I tried to do something like this

import requests
def Get_Child(URL, Name):
        headers = {
            'accept': 'text/plain',
        }

        response = requests.get(
            URL + Name,
            headers=headers)
        json_data = response.json()
        print (json_data)
        list = []
        for locationId in json_data['locationId']:
            list.append(locationId)
            for children in locationId['children']:
                list.append(children)

but that give me the following error,

for children in locationId['locationId']: TypeError: string indices must be integers

Upvotes: 0

Views: 345

Answers (2)

AutoTester213
AutoTester213

Reputation: 2862

I found a solution fro my problem,

The following code will get all the children and append them to a list

class Children():
  def Get_All_Children(self,json_input, lookup_key):
      if isinstance(json_input, dict):
          for k, v in json_input.items():
              if k == lookup_key:
                  yield v
              else:
                  yield from self.Get_All_Children(v, lookup_key)
      elif isinstance(json_input, list):
          for item in json_input:
              yield from self.Get_All_Children(item, lookup_key)


for locations in self.Get_All_Children(self.json_data, 'locationId'):
    self.mylist.append(locations)

Upvotes: 0

gold_cy
gold_cy

Reputation: 14226

Your code shows append, but you ask for a count. Here is a recursive way to get the number of children in this JSON if I am understanding you correctly:

def get_children(body, c=1):
    if not body.get('children'):
        c += 1
    elif isinstance(body.get('children'), list):
            c += 1
            for subchild in body.get('children'):
                c += 1
                get_children(subchild, c)
    return c

counts = get_children(your_json_blob)
print(counts)
>>> 7

Edit: I purposely did not use if/else because I don't know if you can have subchildren that are dict rather than list which would mean you would need extra conditions, but that's up to you if that ends up being the case.

Upvotes: 1

Related Questions