Marlon Abeykoon
Marlon Abeykoon

Reputation: 12465

Create a list of dictionaries which contains nested dictionaries

I have a list of dictionaries as follows,

[{"vehicle_class": "c1", "vehicle_class_count1": 16, "vehicle_usage_count1": 29, "vehicle_usage": "u1", "vehicle_type_count1": 16, "vehicle_type": "t1"}, {"vehicle_class": "c2", "vehicle_class_count1": 11, "vehicle_usage_count1": 29, "vehicle_usage": "u1", "vehicle_type_count1": 11, "vehicle_type": "t1"},{"vehicle_class": "c2", "vehicle_class_count1": 1, "vehicle_usage_count1": 29, "vehicle_usage": "u2", "vehicle_type_count1": 1, "vehicle_type": "t3"},{"vehicle_class": "c3", "vehicle_class_count1": 1, "vehicle_usage_count1": 29, "vehicle_usage": "u2", "vehicle_type_count1": 1, "vehicle_type": "t2"}]

from which I want to form a another list of dictionaries as follows,

[
                {
                    "name": "u1",
                    "imageURL": "",
                    "type": "u1",
                    "children": [
                        {
                            "name": "t1",
                            "imageURL": "",
                            "type": "t1",
                            "size": 9221
                            "children" : [
                                    {"name": "c1",
                                    "imageURL": "",
                                    "type": "c1",
                                    "size": 9221},
                                    {"name": "c2",
                                    "imageURL": "",
                                    "type": "c2",
                                    "size": 9221}
                            ]
                        }
                    ],
                    "size": 10393
                },
                {
                    "name": "u2",
                    "imageURL": "",
                    "type": "u2",
                    "children": [
                        {
                            "name": "t2",
                            "imageURL": "",
                            "type": "t2",
                            "size": 9221,
                            "children":[
                                    "name": "c3",
                                    "imageURL": "",
                                    "type": "c3",
                                    "size": 9221
                            ]
                        },
                        {
                            "imageURL": "",
                            "type": "t3",
                            "name": "t3",
                            "size": 1058,
                            "children": [
                                    "imageURL": "",
                                    "type": "c2",
                                    "name": "c2",
                                    "size": 1058
                            ]
                        }

                    ],
                    "size": 10393
                },

                ]

This is what I have tried so far which I was abel to yield half of the expected result.

result_dict=[] # The above mentioned list comes here
result_list = []
for i in ['vehicle_usage','vehicle_type','vehicle_class']:  # This is a hierarchy which I assign here dynamically can contain any number of values.
    for item in range(0, len(result_dict)):
        for key,value in result_dict[item].items():
         if key == i:
                if not any(d['name'] == value for d in result_list):
                 result = {}
                 result['name'] = value
                 result['imageURL'] = ''
                 result['type'] = value
                 result['size'] = result_dict[item]['%s_count1' % i]
                 if i != len(result_dict):
                     result['children'] =[]
                 print result
                 result_list.append(result)
print result_list # Final list processed according to the required format.

Expected result_list's top level dictionaries must contain vehicle_usage distinct values with respective values like vehicle_usage_count1.

Second levels (i.e children lists) will contain second level etc. This data is sent to a d3 plugin which requires this format.

Number of levels will rely on number of values come to the

['vehicle_usage','vehicle_type','vehicle_class']

From my code all the levels are written to the same level. I want them to write to the correct children list.

Upvotes: 0

Views: 95

Answers (1)

abrunet
abrunet

Reputation: 1122

This is far from perfection but I think it is working.

datalist = [{"vehicle_class": "c1", "vehicle_class_count1": 16, "vehicle_usage_count1": 29, "vehicle_usage": "u1", "vehicle_type_count1": 16, "vehicle_type": "t1"}, {"vehicle_class": "c2", "vehicle_class_count1": 11, "vehicle_usage_count1": 29, "vehicle_usage": "u1", "vehicle_type_count1": 11, "vehicle_type": "t1"},{"vehicle_class": "c2", "vehicle_class_count1": 1, "vehicle_usage_count1": 29, "vehicle_usage": "u2", "vehicle_type_count1": 1, "vehicle_type": "t3"},{"vehicle_class": "c3", "vehicle_class_count1": 1, "vehicle_usage_count1": 29, "vehicle_usage": "u2", "vehicle_type_count1": 1, "vehicle_type": "t2"}]

levels_index = {1: 'vehicle_usage', 2: 'vehicle_type', 3: 'vehicle_class'}


result = []


def build_node(obj, key):
    '''This build the node for your result list'''
    return {
        'name': obj[key],
        'imageURL': '',
        'type': obj[key],
        'size': obj['%s_count1' % key],
        'children': []
    }


def build_level(input_list, keyindex):
    ''' This build one level at a time but call itself recursively'''
    key = levels_index[keyindex]
    levels_memory = {'vehicle_usage': [], 'vehicle_type': [], 'vehicle_class': []}
    output = []
    for obj in input_list:
        if obj[key] not in levels_memory[key]:
            levels_memory[key].append(obj[key])
            output.append(build_node(obj, key))
            if keyindex < len(levels_index):
                output[-1]['children'] = build_level(
                    [_ for _ in input_list if _[key] == output[-1]['name']],
                    keyindex + 1)
    return output


print build_level(datalist, 1)

This gives me the following output

[
    {
        'children': [
            {
                'children': [
                    {
                        'children': [],
                        'imageURL': '',
                        'type': 'c1',
                        'name': 'c1',
                        'size': 16
                    }, {
                        'children': [],
                        'imageURL': '',
                        'type': 'c2',
                        'name': 'c2',
                        'size': 11
                    }],
                'imageURL': '',
                'type': 't1',
                'name': 't1',
                'size': 16}],
        'imageURL': '',
        'type': 'u1',
        'name': 'u1',
        'size': 29
    }, {
        'children': [{
            'children': [],
            'imageURL': '',
            'type': 't3',
            'name': 't3',
            'size': 1
        }, {
            'children': [{
                'children': [],
                'imageURL': '',
                'type': 'c3',
                'name': 'c3',
                'size': 1
            }],
            'imageURL': '',
            'type': 't2',
            'name': 't2',
            'size': 1
        }],
        'imageURL': '',
        'type': 'u2', 
        'name': 'u2',
        'size': 29
    }
]

Upvotes: 1

Related Questions