Home > database >  How to get multiple key value pairs from list of JSON dictionaries
How to get multiple key value pairs from list of JSON dictionaries

Time:02-02

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

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

CodePudding user response:

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

CodePudding user response:

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 expect (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']}]}
  • Related