1

All,

I am trying to change the way some json looks by going through and formatting it in the following way:

1. flatten all of the fields lists
2. Then remove the fields lists and replace them with the name : flatten list

Example:

{
"name": "",
"fields": [{
        "name": "keys",
        "fields": [{
                "node-name": "0/0/CPU0"
            },
            {
                "interface-name": "TenGigE0/0/0/47"
            },
            {
                "device-id": "ASR9K-H1902.corp.cisco.com"
            }
        ]
    },
    {
        "name": "content",
        "fields": [{
            "name": "lldp-neighbor",
            "fields": [{
                    "receiving-interface-name": "TenGigE0/0/0/47"
                },
                {
                    "receiving-parent-interface-name": "Bundle-Ether403"
                },
                {
                    "device-id": "ASR9K-H1902.corp.cisco.com"
                },
                {
                    "chassis-id": "78ba.f975.a64f"
                },
                {
                    "port-id-detail": "Te0/1/0/4/0"
                },
                {
                    "header-version": 0
                },
                {
                    "hold-time": 120
                },
                {
                    "enabled-capabilities": "R"
                },
                {
                    "platform": ""
                }
            ]
        }]
    }
]
}

Would turn into:

{
"": [{

        "keys": [{
            "node-name": "0/0/CPU0",
            "interface-name": "TenGigE0/0/0/47",
            "device-id": "ASR9K-H1902.corp.cisco.com"
        }]
    },
    {
        "content": [{
            "lldp-neighbor": [{
                "receiving-interface-name": "TenGigE0/0/0/47",
                "receiving-parent-interface-name": "Bundle-Ether403",
                "device-id": "ASR9K-H1902.corp.cisco.com",
                "chassis-id": "78ba.f975.a64f",
                "port-id-detail": "Te0/1/0/4/0",
                "header-version": 0,
                "hold-time": 120,
                "enabled-capabilities": "R",
                "platform": ""
            }]
        }]
    }
]
}

I have tried the following to get the list flattened:

def _flatten_fields(self, fields_list):
        c = {}
        for b in [d for d in fields_list if bool(d)]:
                c.update(b)
        return c

This seems to work but I can't figure out a way to get into the sub levels using recursion, I am saving all flatten lists and names into a new dictionary, is there a way to do it by just manipulating the original dictionary?

2 Answers 2

1

This worked on the example you provided:

import json

def flatten(data):
    result = dict()
    if isinstance(data, dict):
        if 'name' in data:
            name = data['name']
            result[name] = flatten(data['fields'])
        else:
            key = data.keys()[0]
            value = data.values()[0]
            result[key] = value
    else:
        for entry in data:
            result.update(flatten(entry))
    return result

print json.dumps(flatten(data), indent=4)

Output

{
    "": {
        "keys": {
            "node-name": "0/0/CPU0", 
            "interface-name": "TenGigE0/0/0/47", 
            "device-id": "ASR9K-H1902.corp.cisco.com"
        }, 
        "content": {
            "lldp-neighbor": {
                "receiving-interface-name": "TenGigE0/0/0/47", 
                "receiving-parent-interface-name": "Bundle-Ether403", 
                "header-version": 0, 
                "port-id-detail": "Te0/1/0/4/0", 
                "chassis-id": "78ba.f975.a64f", 
                "platform": "", 
                "device-id": "ASR9K-H1902.corp.cisco.com", 
                "hold-time": 120, 
                "enabled-capabilities": "R"
            }
        }
    }
}

It doesn't have the extra list layers shown in your expected output, but I don't think you want those.

Sign up to request clarification or add additional context in comments.

Comments

0

This worked on the example you provided:

def flatten_fields(fields_list):

    c = {}
    for item in fields_list:
        for key in item:
            if key == "fields":
                c[item["name"]] = flatten_fields(item["fields"])
            elif key != "name":
                c[key] = item[key]
            break

    return [c]

But it works on a list of dictionaries, so you should call it like flatten_fields([data])[0].

The output is:

{
"": [{
    "keys": [{
        "node-name": "0/0/CP0", 
        "interface-name": "TenGigE0/0/0/47", 
        "device-id": "ASR9K-H1902.corp.cisco.com"
        }], 
    "content": [{
        "lldp-neighbor": [{
            "chassis-id": "78ba.f975.a64f", 
            "receiving-parent-interface-name": "Bndle-Ether403", 
            "enabled-capabilities": "R", 
            "device-id": "ASR9K-H1902.corp.cisco.com", 
            "hold-time": 120, 
            "receiving-interface-name": "TenGigE0/0/0/47", 
            "platform": "", 
            "header-version": 0, 
            "port-id-detail": "Te0/1/0/4/0"
            }]
        }]
    }]
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.