Build a graph recursively - breadth first - python

i want to build a "graph" in the following style:
{
"name":cersei
"children": [
{
"name": "baratheon",
"children": [
{
"name": "cersei",
"children": []
},
{
"name": "baratheon",
"children": [],
}
],
},
{
"name": "joffrey",
"children": [
{
"name": "robert",
"children": []
},
{
"name": "cersei",
"children": []
}
]
}
]
}
But i build this via depth-first. That means the first element of "children" is fully build, after that the second element of "children" is build. This is the recurse-function:
def recurse(dicts, depth):
if depth >=0:
dicts["children"] = []
child_elements = [] //do something to get your child-elements
for child in child_elements:
if depth >=0:
child_dict = dict(name=word[0])
dicts["children"].append(child_dict)
recurse(child_dict, depth-1)
How can i change the code that it builds the whole "level" first and appends the childrens-children later? I've got the problem, that i don't know how to call the level 1 dictionary, because its kind of a dictionary in the dictionary...
Kind regards and thanks for your help, FFoDWindow.
--------------------****UPDATE****---------------------------
I solved the issue myself. Actually it was pretty simple. I only had to save the temporarly build "children"-elements in an extra list. Now the tree is build breadth-first. Here is my recurse function:
def recurse( input_dict, level_list, depth):
next_level_list = []
for dictionary in input_dict:
child_elements = [...] //get the data for your children
for child_element in child_elements:
dictionary["children"].append = dict(name = child_element)
next_level_list.append(dictionary["children"][-1])
if depth >=0:
recurse(input_dict, next_level_list, depth-1)

Related

building json tree from list of file paths

I have list of file paths and need them to be organized in a tree structure like the following.
{
"label": "VP Accounting",
"children": [
{
"label": "iWay",
"children": [
{
"label": "Universidad de Especialidades del EspĂ­ritu Santo"
},
{
"label": "Marmara University"
},
{
"label": "Baghdad College of Pharmacy"
}
]
},
{
"label": "KDB",
"children": [
{
"label": "Latvian University of Agriculture"
},
{
"label": "Dublin Institute of Technology"
}
]
},
what I did so far is the following
output = {}
current = {}
for path in paths :
current = output
for segment in path.split("/") :
if segment != '':
if segment not in current:
current[segment] = {}
current = current[segment]
The output is a tree like structure but I can not add the keys ["label", "children"]
The idea is to maintain the dictionary that your code is building as an auxiliary helper structure (which is called helper below, and is simplified to a flat dictionary), and to create the other (desired) structure in parallel (having the lists).
Note that the top level should really be a list as it is not guaranteed all entries will start with the same folder ("segment").
Here is your code adapted to create the children lists and add the labels:
output = []
root = { "children": output }
helper = {}
for path in paths:
current = root
subpath = ""
for segment in path.split("/"):
if "children" not in current:
current["children"] = []
subpath += "/" + segment
if subpath not in helper:
helper[subpath] = { "label": segment }
current["children"].append(helper[subpath])
current = helper[subpath]
print(output)

how to read dictionary key and values from a nested list and dictionary

I have following dictionary with nested dictionary and lists, was trying to output the values for all the keys "name".
i couldn't figure out the logic to implement on this dictionary
expecting output like
test
inside_test
inner_group1
GetFTP
Dictionary data:
{
"id": "0ce8df69-016b-1000-ffff-ffffbe50cb53",
"name": "test",
"processGroupStatusSnapshot": {
"name": "test",
"connectionStatusSnapshots": [],
"processorStatusSnapshots": [],
"processGroupStatusSnapshots": [
{
"id": "0ce90089-016b-1000-ffff-ffffadb84af5",
"processGroupStatusSnapshot": {
"name": "inside_test",
"connectionStatusSnapshots": [],
"processorStatusSnapshots": [],
"processGroupStatusSnapshots": [
{
"id": "0ce97287-016b-1000-0000-000056414ae7",
"processGroupStatusSnapshot": {
"id": "0ce97287-016b-1000-0000-000056414ae7",
"name": "inner_group1",
"connectionStatusSnapshots": [],
"processorStatusSnapshots": [
{
"id": "0ce9ca47-016b-1000-0000-0000496a342d",
"processorStatusSnapshot": {
"id": "0ce9ca47-016b-1000-0000-0000496a342d",
"groupId": "0ce97287-016b-1000-0000-000056414ae7",
"name": "GetFTP"
}
}
],
"processGroupStatusSnapshots": [],
"remoteProcessGroupStatusSnapshots": [],
"inputPortStatusSnapshots": [],
"outputPortStatusSnapshots": []
}
}
]
}
}
]
}
}
Given the nesting, and the fact that key names will remain same in all levels, I think a recursive solution will work best here. Please feel free to use this solution as reference and modify based on your needs.
Argument d is the dictionary here.
def find_name(d):
if 'processGroupStatusSnapshot' in d:
print("Name =", d['processGroupStatusSnapshot']['name'])
nxt = d['processGroupStatusSnapshot']['processGroupStatusSnapshots']
if len(nxt) > 0:
find_name(nxt[0])
find_name(d)

Converting pandas Dataframe to nested json key pair

Here is a sample data from a csv file, where every generation is children of previous generation.
parant,gen1,gen2,get3,gen4,gen5,gen6
query1,AggregateExpression,abc,def,emg,cdf,bcf
query1,And,cse,rds,acd,,
query2,Arithmetic,cbd,rsd,msd,,
query2,Average,as,vs,ve,ew,
query2,BinaryExpression,avsd,sfds,sdf,,
query2,Comparison,sdfs,sdfsx,,,
query3,Count,sfsd,,,,
query3,methods1,add,asd,fdds,sdf,sdf
query3,methods1,average,sdfs,bf,fd,
query4,methods2,distinct,cz,asd,ada,
query4,methods2,eq,sdfs,sdfxcv,sdf,rtyr
query4,methods3,eq,vcx,xcv,cdf,
I need to create a json file of following format, where parents are the index and children are always list of dictionaries and there is a size for the last generation which is calculated no. of time their parent appear (in previous generation).
Example of the first row breakdown:
{
"name": "query1",
"children": [
{
"name": "AggregateExpression",
"children": [
{
"name": "abc",
"children": [
{
"name": "def",
"children": [
{
"name": "emg",
"children": [
{
"name": "cdf",
"children": [
{
"name": "bcf", "size": 1
}
]
}
]
}
]
}
]
}
]
}
]
}
I have tried to use groupby() and to_json() but was not able to complete. But still struggling to build the logic if I need to use lambda or looping. Any suggestion or solution is welcome. Thanks.

convert file path list to tree

There is a python file path list like below:
file_path_list = ["test/dir1/log.txt", "test/dir1/dir2/server.txt", "test/manage/img.txt"]
I want to convert it to a tree. the expect result is below:
tree_data = [
{
"path": "test",
"children": [
{
"path": "dir1",
"children": [
{
"path": "log.txt"
},
{
"path": "dir2",
"children": [
{
"path": "server.txt"
}
]
}
]
},
{
"path": "manage",
"children": [
{
"path": "img.txt",
}
]
}
]
}
]
What's the best way to convert?
update: my code is below, but I think it's not well.
def list2tree(file_path):
"""Convert list to tree."""
tree_data = [{
"path": "root",
"children": []
}]
for f in file_path:
node_path = tree_data[0]
pathes = f.split("/")
for i, p in enumerate(pathes):
length = len(node_path["children"])
if not length or node_path["children"][length - 1]["path"] != p:
# create new node
new_node = {
"path": p,
}
if i != len(pathes) - 1: # middle path
new_node["children"] = list()
node_path["children"].append(new_node)
node_path = new_node
else:
node_path = node_path["children"][length - 1]
return tree_data
I think this way is not the best. any ideas? Thank you very much!
One way is to split the strings at '/' and put them in a defaultdict of defaultdicts, see defaultdict of defaultdict, nested.

Manipulating data structures in Python

I have data in JSON format:
data = {"outfit":{"shirt":"red,"pants":{"jeans":"blue","trousers":"khaki"}}}
I'm attempting to plot this data into a decision tree using InfoVis, because it looks pretty and interactive. The problem is that their graph takes JSON data in this format:
data = {id:"nodeOutfit",
name:"outfit",
data:{},
children:[{
id:"nodeShirt",
name:"shirt",
data:{},
children:[{
id:"nodeRed",
name:"red",
data:{},
children:[]
}],
}, {
id:"nodePants",
name:"pants",
data:{},
children:[{
id:"nodeJeans",
name:"jeans",
data:{},
children:[{
id:"nodeBlue",
name:"blue",
data:{},
children[]
},{
id:"nodeTrousers",
name:"trousers",
data:{},
children:[{
id:"nodeKhaki",
name:"khaki",
data:{},
children:[]
}
}
Note the addition of 'id', 'data' and 'children' to every key and value and calling every key and value 'name'. I feel like I have to write a recursive function to add these extra values. Is there an easy way to do this?
Here's what I want to do but I'm not sure if it's the right way. Loop through all the keys and values and replace them with the appropriate:
for name, list in data.iteritems():
for dict in list:
for key, value in dict.items():
#Need something here which changes the value for each key and values
#Not sure about the syntax to change "outfit" to name:"outfit" as well as
#adding id:"nodeOutfit", data:{}, and 'children' before the value
Let me know if I'm way off.
Here is their example http://philogb.github.com/jit/static/v20/Jit/Examples/Spacetree/example1.html
And here's the data http://philogb.github.com/jit/static/v20/Jit/Examples/Spacetree/example1.code.html
A simple recursive solution:
data = {"outfit":{"shirt":"red","pants":{"jeans":"blue","trousers":"khaki"}}}
import json
from collections import OrderedDict
def node(name, children):
n = OrderedDict()
n['id'] = 'node' + name.capitalize()
n['name'] = name
n['data'] = {}
n['children'] = children
return n
def convert(d):
if type(d) == dict:
return [node(k, convert(v)) for k, v in d.items()]
else:
return [node(d, [])]
print(json.dumps(convert(data), indent=True))
note that convert returns a list, not a dict, as data could also have more then one key then just 'outfit'.
output:
[
{
"id": "nodeOutfit",
"name": "outfit",
"data": {},
"children": [
{
"id": "nodeShirt",
"name": "shirt",
"data": {},
"children": [
{
"id": "nodeRed",
"name": "red",
"data": {},
"children": []
}
]
},
{
"id": "nodePants",
"name": "pants",
"data": {},
"children": [
{
"id": "nodeJeans",
"name": "jeans",
"data": {},
"children": [
{
"id": "nodeBlue",
"name": "blue",
"data": {},
"children": []
}
]
},
{
"id": "nodeTrousers",
"name": "trousers",
"data": {},
"children": [
{
"id": "nodeKhaki",
"name": "khaki",
"data": {},
"children": []
}
]
}
]
}
]
}
]

Categories