skip to Main Content

I have a JSON file called "hostnames" formatted like below

{
    'propertyName': 'www.property1.com',
    'propertyVersion': 1,
    'etag': 'jbcas6764023nklf78354',
    'rules': {
        'name': 'default',
        'children': [{
            'name': 'Route',
            'children': [],
            'behaviors': [{
                'name': 'origin',
                'options': {
                    'originType': 'CUSTOMER',
                    'hostname': 'www.origin1.com',

and I wanted to get the values of keys "propertyName" and "hostname" and have a new JSON file like below

'properties': [{
    'propertyName': 'www.property1.com',
    'hostnames': ['www.origin1.com', 'www.origin2.com']
}, {
    'propertyName': 'www.property1.com',
    'hostnames': ['www.origin1.com', 'www.origin2.com']
}]

my code looks like this

hostnames = result.json()
hostnameslist = [host['hostname'] for host in hostnames['rules']['children']['behaviors']['options']]
print(hostnameslist)

but I’m getting the error

TypeError: list indices must be integers or slices, not str

2

Answers


  1. You are trying to access a list elements with a string index (‘behaviors’).
    Try:

    hostnames = result.json()
    hostnameslist = []
    for child in hostnames['rules']['children']:
        for behavior in child['behaviors']:
            if behavior['name'] == 'origin':
                hostnameslist.append(behavior['options']['hostname'])
    
    properties = [{
        'propertyName': hostnames['propertyName'],
        'hostnames': hostnameslist
    }]
    
    Login or Signup to reply.
  2. Making an assumption about how the OP’s data might be structured.

    Recursive navigation of the dictionary to find all/any values associated with a dictionary key of ‘hostname’ appears to be well-suited here.

    Doing it this way obviates the need for knowledge about the depth of the dictionary or indeed any of the dictionary key names except (obviously) ‘hostname’.

    Of course, there may be other dictionaries within the "master" dictionary that contain a ‘hostname’ key. If that’s the case then this function may return values that are not needed/wanted.

    data = {
        'propertyName': 'www.property1.com',
        'propertyVersion': 1,
        'etag': 'jbcas6764023nklf78354',
        'rules': {
            'name': 'default',
            'children': [{
                'name': 'Route',
                'children': [],
                'behaviors': [{
                    'name': 'origin',
                    'options': {
                        'originType': 'CUSTOMER',
                        'hostname': 'www.origin1.com'
                    }
                },
                {
                    'name': 'origin',
                    'options': {
                        'originType': 'CUSTOMER',
                        'hostname': 'www.origin2.com'
                    }
                }
                ]
            }
            ]
        }
    }
    
    def get_hostnames(d):
        def _get_hostnames(_d, _l):
            if isinstance(_d, dict):
                if 'hostname' in _d:
                    _l.append(_d['hostname'])
                else:
                    for _v in _d.values():
                        _get_hostnames(_v, _l)
            else:
                if isinstance(_d, list):
                    for _v in _d:
                        _get_hostnames(_v, _l)
            return _l
        return _get_hostnames(d, [])
    
    
    result = {'properties': [{'propertyName': data.get('propertyName'), 'hostnames': get_hostnames(data)}]}
    
    print(result)
    

    Output:

    {'properties': [{'propertyName': 'www.property1.com', 'hostnames': ['www.origin1.com', 'www.origin2.com']}]}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search