Recursive seek throught python dictionary to create Graphwiz
Clash Royale CLAN TAG#URR8PPP
Recursive seek throught python dictionary to create Graphwiz
I've got dictionary with such body:
[
"children": [
"children": [
"children": [
"label": "Something20",
"id": 11
,
"label": "Something19",
"id": 12
],
"label": "Something18",
"id": 5
,
"children": [
"label": "Something15",
"id": 13
],
"label": "Something14",
"id": 6
],
"label": "Something2",
"id": 2
,
"children": [
"children": [
"label": "Something10",
"id": 14
],
"label": "Something9",
"id": 7
,
"label": "Something8",
"id": 8
],
"label": "Somethin7",
"id": 3
,
"children": [
"label": "Something5",
"id": 9
,
"label": "Something4",
"id": 10
],
"label": "Something2",
"id": 4
],
"label": "Something1",
"id": 1
]
How can I recursively seek throught this dict to generate Graphviz data like this:
Something1->Something2
Something1->Something7
So e.g. list called edges =
and append to it some data as touples (only labels):
edges =
[("Something1", "Something2"), ("Something1", "Something7")]
After data is generated I can then simply genarate object in GraphWiz (Generate PNG Image) representing tree structure of provided dictionary.
1 Answer
1
If you want to do this recursively, you can have a function, that generates an edge from the node it is passed to each of its children, as well as calling itself for each of the children. Then all you need to do is call it for every node in the root list (and you need to collect all generated edges in a list). This could be implemented as follows (root
holds your data):
root
def get_edges(node):
if "children" not in node: # ensure the node has children
return
label = node["label"]
children = node["children"]
result = [(label, c["label"]) for c in children] # create the edges
for c in children:
result.extend(get_edges(c)) # travers the tree recursively and collect all edges
return result
edges = sum(map(get_edges, root), ) # create and combine all the edge lists
Running this code with the data you provided yields the following:
[('Something1', 'Something2'), ('Something1', 'Somethin7'),
('Something1', 'Something2'), ('Something2', 'Something18'),
('Something2', 'Something14'), ('Something18', 'Something20'),
('Something18', 'Something19'), ('Something14', 'Something15'),
('Somethin7', 'Something9'), ('Somethin7', 'Something8'),
('Something9', 'Something10'), ('Something2', 'Something5'),
('Something2', 'Something4')]
I think it is happening because not always node containt 'children' key.
– needtobe
Aug 13 at 7:42
I have added a check, to ensure the node has children. But that solves a different problem the code had (if a node does not have children, python will give you a
KeyError: 'children'
, not the TypeError
you described). I would guess that there is a node in your data, which has a child which is only a string, not a dictionary. I have tested the code with the data you provided and added the results to my answer.– Leon
Aug 13 at 9:55
KeyError: 'children'
TypeError
Thank you very much! I figured out similar thing: if not children: return [ ] .
– needtobe
Aug 13 at 12:49
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Unfortunately it returns TypeError: string indices must be integers
– needtobe
Aug 13 at 7:29