0

If my JSON data looks like this:

{
    "name": "root",
    "children": [
        {
            "name": "a",
            "children": [
                {
                    "name": "b",
                    "children": [
                        {
                            "name": "c",
                            "size": "1"
                        },
                        {
                            "name": "d",
                            "size": "2"
                        }
                    ]
                },
                {
                    "name": "e",
                    "size": 3
                }
            ]
        },
        {
            "name": "f",
            "children": [
                {
                    "name": "g",
                    "children": [
                        {
                            "name": "h",
                            "size": "1"
                        },
                        {
                            "name": "i",
                            "size": "2"
                        }
                    ]
                },
                {
                    "name": "j",
                    "size": 5
                }
            ]
        }
    ]
}

How can I return two adjacent levels in Python?

For example return:
a - b,e
f - g,j

The data could become very large, therefore I have to slice it into smaller pieces.

Thanks for every help.

simeck
  • 3
  • 2
  • 4
    Tell us [what you've tried](https://stackoverflow.com/help/how-to-ask), and where you are stuck. This will also help us answer your question better. – SSC Dec 18 '18 at 07:18
  • Do you realise that JSON is a *notation*, and parsing/loading it gives you regular Python containers and values? Do you know how to slice/index Pythonˋs list and dict types? – MisterMiyagi Dec 18 '18 at 07:35
  • I used json.loads() to create a nested dict, but I am stuck at referencing certain data. I tried to use multiple for-loops, but I could not get it to work and think there could be better solutions. (Sorry, I am new to Python as well as Stackoverflow) – simeck Dec 18 '18 at 07:39
  • What data structure do you need at the end? What you have shown is not a valid Python data structure. Should ˋbˋ also contain ˋcˋ and ˋdˋ, I.e. do you just want to remove the „name“ and „children“ keys? What about the „size“ field? – MisterMiyagi Dec 18 '18 at 07:39
  • In the end I need a dict containing every information given like in the origin data (name, children, size). I want to use it as input for a component (Sunburst chart) which is based on a D3 component. – simeck Dec 18 '18 at 07:47

2 Answers2

0

Try this solution, tell me this works or not.

dictVar = {
    "name": "root",
    "children": [
        {
            "name": "a",
            "children": [
                {
                    "name": "b",
                    "children": [
                        {
                            "name": "c",
                            "size": "1"
                        },
                        {
                            "name": "d",
                            "size": "2"
                        }
                    ]
                },
                {
                    "name": "e",
                    "size": 3
                }
            ]
        },
        {
            "name": "f",
            "children": [
                {
                    "name": "g",
                    "children": [
                        {
                            "name": "h",
                            "size": "1"
                        },
                        {
                            "name": "i",
                            "size": "2"
                        }
                    ]
                },
                {
                    "name": "j",
                    "size": 5
                }
            ]
        }
    ]
}

name = {}
for dobj in dictVar['children']:
    for c in dobj['children']:
        if not dobj['name'] in name:
            name[dobj['name']] = [c['name']]
        else:
            name[dobj['name']].append(c['name'])
print(name)

AND as you need all origin data then another is :

name = {}
for dobj in dictVar['children']:
    for c in dobj['children']:
        if not dobj['name'] in name:
            name[dobj['name']] = [c]
        else:
            name[dobj['name']].append(c)
print(name)
Anup Yadav
  • 2,825
  • 3
  • 21
  • 30
0

You need to build a tree of dicts, with values as the leaves:

{'a': {'b': {'c': '1', 'd': '2'}, 'e': '3'}, 'f': {'g': {'h': '1', 'i': '2'}, 'j': '5'}}

This can be decomposed into three separate actions:

  1. get the "name" of a node for use as a key
  2. if the node has "children", transform them to a dict
  3. if the node has a "size", transform that to the single value

Unless your data is deeply nested, recursion is a straightforward approach:

def compress(node: dict) -> dict:
    name = node['name']  # get the name
    try:
        children = node['children']  # get the children...
    except KeyError:
        return {name: node['size']}  # or return name and value
    else:
        data = {}
        for child in children:       # collect and compress all children
            data.update(compress(child))
        return {name: data}

This compresses the entire hierarchy, including the "root" node:

 >>> compress(data)
 {'root': {'a': {'b': {'c': '1', 'd': '2'}, 'e': 3},
           'f': {'g': {'h': '1', 'i': '2'}, 'j': 5}}}
MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119