Issue
I have a list of dicts in python that represents an adjacency list and i want to transform this list in to a nested python dict. with name
and children
keys.
List of nodes
This is an example of the list of dicts, those are the 10 first elements of the list. The original contains 1000 elements.
[{'id': 1, 'name': 'External sector', 'parent_id': 0},
{'id': 3, 'name': 'Capital and financial markets', 'parent_id': 0},
{'id': 77, 'name': 'Credit indicators', 'parent_id': 0},
{'id': 15, 'name': 'Economic activity', 'parent_id': 0},
{'id': 17, 'name': 'Monetary indicators', 'parent_id': 0},
{'id': 30, 'name': 'Regional economy', 'parent_id': 0},
{'id': 114, 'name': 'International economy', 'parent_id': 0},
{'id': 157, 'name': 'National private financial system', 'parent_id': 0},
{'id': 176, 'name': 'Financial Stability', 'parent_id': 0},
{'id': 222, 'name': 'Financial Inclusion', 'parent_id': 0}]
What i've tried
I've found this function in SO that is able to transform this list of dicts in to a nested python dict:
def list_to_tree(data):
out = {
# 0: { 'id': 0, 'parent_id': 0, 'name': "Root node", 'sub': [] }
}
for p in data:
out.setdefault(p['parent_id'], { 'sub': [] })
out.setdefault(p['id'], { 'sub': [] })
out[p['id']].update(p)
out[p['parent_id']]['sub'].append(out[p['id']])
return out[0]
This function produces dicts in this way:
{'id': 0,
'name': 'rootnode',
'parent_id': None,
'sub': [{'id': 1,
'name': 'External sector',
'parent_id': 0,
'sub': [{'id': 2,
'name': 'Exchange rates',
'parent_id': 1,
'sub': [{'id': 242,
'name': 'Controlled or free rates',
'parent_id': 2,
'sub': []},
{'id': 243,
'name': 'Floating rates',
'parent_id': 2,
'sub': []},
{'id': 532,
'name': 'Real and effective exchange rate indices',
'parent_id': 2,
'sub': []},
{'id': 533,
'name': 'Foreign exchange and wage indicators',
'parent_id': 2,
'sub': []},
{'id': 548,
'name': 'Average of period',
'parent_id': 2,
'sub': []},
But i wanted to produce dicts in this way, without the id's
{
'name': 'rootnode',
'children': [{
'name': 'External sector',
'children': [{
'name': 'Exchange rates',
'children': [{
'name': 'Controlled or free rates',
'children': []},
{
'name': 'Floating rates',
'children': []},
{
'name': 'Real and effective exchange rate indices',
'children': []},
{
'name': 'Foreign exchange and wage indicators',
'children': []},
{
'name': 'Average of period',
'children': []},
Is there any way that i can change this function that i've found in order to produce the desired output? Any hint, tip or advice is more than welcome.
Solution
You can use the function with slight modifications:
- Use the 'children' key instead of 'sub'
- Initialise the root node with only the keys you want to have (name & children)
- Instead of calling
.update
(which copies all keys), assign just the 'name' key
def list_to_tree(data):
out = {
0: { 'name': 'rootnode', 'children': [] }
}
for p in data:
out.setdefault(p['parent_id'], { 'children': [] })
out.setdefault(p['id'], { 'children': [] })
out[p['id']]['name'] = p['name']
out[p['parent_id']]['children'].append(out[p['id']])
return out[0]
Answered By - trincot
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.