Printing from nested dictionary - python

How to print either 1 specific value, or a select key2 values for all key1 from a nested dictionary? The lines in my code display nothing.
Foe example, how to print (a single value):
Canon-PS-G7-X-Mark-II`
or (select key2 values for all key1):
Canon-PS-G7-X-Mark-II
Nikon-D5
Sony-alpha9
The dictionary (part of it) and code
config = {
'g7': {},
'd5': {},
'a9': {},
}
config['g7']['cam_name'] = ('Canon-PS-G7-X-Mark-II')
config['d5']['cam_name'] = ('Nikon-D5')
config['a9']['cam_name'] = ('Sony-alpha9')
camtype = """
1 camera:
(config['g7']['cam_name'])
all cameras
(config[.]['cam_name'])
"""
print(camtype)

try below code:
config = {
'g7': {},
'd5': {},
'a9': {},
}
config['g7']['cam_name'] = ('Canon-PS-G7-X-Mark-II')
config['d5']['cam_name'] = ('Nikon-D5')
config['a9']['cam_name'] = ('Sony-alpha9')
camtype = """
1 camera:
({0})
all cameras
({1})
"""
single_camera = config['g7']['cam_name']
all_camera = ', '.join([config[k]['cam_name'] for k in config])
print(camtype.format(single_camera, all_camera))
output:
1 camera:
(Canon-PS-G7-X-Mark-II)
all cameras
(['Canon-PS-G7-X-Mark-II', 'Nikon-D5', 'Sony-alpha9'])

I am sure someone else can do better than I.
config = {
'g7': {},
'd5': {},
'a9': {},
}
config['g7']['cam_name'] = ('Canon-PS-G7-X-Mark-II')
config['d5']['cam_name'] = ('Nikon-D5')
config['a9']['cam_name'] = ('Sony-alpha9')
camtype = """1 camera: %s""" %(config['g7']['cam_name']) #search up python print function
allcam = [ value['cam_name'] for key, value in config.items()] #creates list with all cameras
str_allcam = "all cameras " + ', '.join( str(p) for p in allcam) # prints all cameras with a comma seperator
print(camtype +"\n" + str_allcam) # outputs a two lines because of newline seperator

Related

how to convert mindmap csv to python dict and find key

here is the mindmap
and corresponding csv file is
history,Africa,Egyptian,pyramid
,Asia,Ancient India,Caste System
,,,Buddhism
,Eourp,Greece,xxx
,,Rome,yyy
,,,zzzz
I want to convert csv file to json like struct
{
'history': [
{
'Africa': [
{
'Egyptian': [{'pyramid': []}]
}
]
},
{
'Asia': [
{
'Ancient India': [
{'Caste System': []},
{'Buddhism': []}
]
}
]
},
...
]
}
finally a function to find the key and print the path of that key
e.g. find('Buddhism') -> history.Asia.Ancient India.Buddhism
I've tried Tree but I have no idea how to achieve this.
Here's a working solution:
# Load your string into list of list
m = []
for each in s.split('\n'):
l = each.split(',')
m.append(l)
# Create dict object that you want.
master = {}
level_indexes = [-1]*10
for i in range(len(m)):
level = len([e for e in m[i] if e == ''])
level_indexes[level] = i
level_indexes[level+1:] = [-1]*(10-level-1)
if level == 0:
head = master
for each in m[i]:
head[each] = {}
head = head[each]
else:
head = master
indexes = []
for j, e in enumerate(level_indexes[:level]):
if e is not -1:
indexes.append(j)
indexes.append(level)
last = []
for j in range(len(indexes)-1):
last.extend(m[level_indexes[j]][indexes[j]:indexes[j+1]])
for j in range(level):
head = head[last[j]]
for j in range(level, len(m[i])):
head[m[i][j]] = {}
head = head[m[i][j]]
This creates a nested dictionary - master:
{'history': {'Africa': {'Egyptian': {'pyramid': {}}},
'Asia': {'Ancient India': {'Buddhism': {}, 'Caste System': {}}},
'Eourp': {'Greece': {'xxx': {}},
'Rome': {'yyy': {}, 'zzzz': {}}}}}
If you tweak it a little bit, you can put everything in list, but that will make it much more complicated:
master = []
level_indexes = [-1]*10
for i in range(len(m)):
level = len([e for e in m[i] if e == ''])
level_indexes[level] = i
level_indexes[level+1:] = [-1]*(10-level-1)
if level == 0:
head = master
for each in m[i]:
head.append({each: []})
head = head[-1][each]
else:
head = master
indexes = []
for j, e in enumerate(level_indexes[:level]):
if e is not -1:
indexes.append(j)
indexes.append(level)
last = []
for j in range(len(indexes)-1):
last.extend(m[level_indexes[j]][indexes[j]:indexes[j+1]])
for j in range(level):
head = head[-1][last[j]]
for j in range(level, len(m[i])):
head.append({m[i][j]: []})
head = head[-1][m[i][j]]
output:
[{'history': [{'Africa': [{'Egyptian': [{'pyramid': []}]}]},
{'Asia': [{'Ancient India': [{'Caste System': []},
{'Buddhism': []}]}]},
{'Eourp': [{'Greece': [{'xxx': []}]},
{'Rome': [{'yyy': []}, {'zzzz': []}]}]}]}]

Keep duplicate values in dict when updated

I am using the following code to convert a dict to json and send this to processing by javascript.
the code reads from an excel file and updates the nested_dict.
the issue I have is when there are 2 similar values in the excel spreadsheet, obviously the dict once updated will ignore the earlier value.
How am I able to keep all duplicates please, see example of nested_dict below.
Code:
book = xlrd.open_workbook(offer_path)
first_sheet = book.sheet_by_index(1)
nested_dict = {}
nested_dict["Design_Lump_Sum"] = {}
#print nested_dict
for i in range(12,19):
design_cells = first_sheet.row_slice(rowx=i, start_colx=2, end_colx=4)
if str(design_cells[0].value) and str(design_cells[1].value):
if design_cells[1].value >0 :
nested_dict["Design_Lump_Sum"].update({str(design_cells[0].value) : str(design_cells[1].value)})
nested_dict["Capex_Lump_Sum"] = {}
for i in range(22,155):
capex_cells = first_sheet.row_slice(rowx=i, start_colx=2, end_colx=4)
if str(capex_cells[0].value) and str(capex_cells[1].value):
if capex_cells[1].value >0 :
nested_dict["Capex_Lump_Sum"].update({str(capex_cells[0].value) : str(capex_cells[1].value)})
nested_dict["Opex_Lump_Sum"] = {}
for i in range(157,175):
Opex_cells = first_sheet.row_slice(rowx=i, start_colx=2, end_colx=4)
if str(Opex_cells[0].value) and str(Opex_cells[1].value):
if Opex_cells[1].value >0 :
nested_dict["Opex_Lump_Sum"].update({str(Opex_cells[0].value) : str(Opex_cells[1].value)})
nested_dict["Provisional_Sum"] = {}
for i in range(176,198):
Provisional_cells = first_sheet.row_slice(rowx=i, start_colx=2, end_colx=4)
if str(Provisional_cells[0].value) and str(Provisional_cells[1].value):
if Provisional_cells[1].value >0 or Provisional_cells[1].value <0:
nested_dict["Provisional_Sum"].update({str(Provisional_cells[0].value) : str(Provisional_cells[1].value)})
nested_dict["Management_fees"] = {}
for i in range(200,209):
Management_fees = first_sheet.row_slice(rowx=i, start_colx=2, end_colx=4)
if str(Management_fees[0].value) and str(Management_fees[1].value):
if Management_fees[1].value >0 :
nested_dict["Management_fees"].update({str(Management_fees[0].value) : str(Management_fees[1].value)})
nested_dict["CSA"] = {}
for i in range(211,231):
CSA = first_sheet.row_slice(rowx=i, start_colx=2, end_colx=4)
if str(CSA[0].value) and str(CSA[1].value):
if CSA[1].value >0 or CSA[1].value <0 :
nested_dict["CSA"].update({str(CSA[0].value) : str(CSA[1].value)})
nested_dict["Total"] = {}
nested_dict["Total"].update({"sub_Total": str(first_sheet.cell(234,3))})
print nested_dict
return json.dumps(nested_dict)
List output example printed by the code below:
{'Management_fees': {}, 'Capex_Lump_Sum': {'Refrigerant piping':
'48040.447', 'Preparation of Mops': '2137.681', 'Labels': '653.016',
'Penetrations and Protection': '1535.534', 'AC Plinth and Trays':
'5221.762', 'Insulated Panel Windows': '6527.794', ' MSSB':
'19582.199', 'Make Good Walls and Floors': '4154.696', 'Controls':
'24092.978', '** Building Surveyor Fee (Misc)': '7038.85', 'Project
Manag ement, Supervision': '38447.5', 'Painting': '9138.675',
'Preliminaries': '1306.032', 'Package system wiring': '16971.318',
'Warranty': '2610.881', 'Ductwork, Valves and Dampers': '77262.913',
'Unit ty pe': '89107.109', 'Structural Engineer for new unit stands':
'3916.913', 'Manuals': '3823.456', 'AMS and BMS works': '3916.913',
'Accoustic Report': '4243.421', 'Lighting': '5033.665', 'Drawings':
'38
23.456', 'Temp Cooling': '10443.524', 'Commissioning': '3263.897', 'Crane': '3003.637', 'Demolition': '26455.429', 'Fire detection and
Alarm FIP modifications': '3263.897', 'LSL': '1939.81059657', 'Ec
onomy Cycle': '23169.055'}, 'Provisional_Sum': {'Condenser Roof
Platform': '20000.0', 'Removal of ladder outside cable chamber exit
stairs': '10000.0'}, 'Opex_Lump_Sum': {}, 'CSA': {'Additional Hendry
Fees': '3742.5', 'External Ladder': '10147.0', 'Asbestos removal Works
Total ($42,485.15) (remainder of cost $30K under PS sum)':
'12485.15'}, 'Design_Lump_Sum': {'** Detailed Design': '15379.0', '*
* Const Stage Services': '4732.0', '** Preliminary Design': '2366.0'}, 'Total': {'sub_Total': 'number:530154.0105965699'}}

Extracting data from string with specific format using Python

I am novice with Python and currently I am trying to use it to parse some custom output formated string. In fact format contains named lists of float and lists of tuples of float. I wrote a function but it looks excessive. How can it be done in more suitable way for Python?
import re
def extract_line(line):
line = line.lstrip('0123456789# ')
measurement_list = list(filter(None, re.split(r'\s*;\s*', line)))
measurement = {}
for elem in measurement_list:
elem_list = list(filter(None, re.split(r'\s*=\s*', elem)))
name = elem_list[0]
if name == 'points':
points = list(filter(None, re.split(r'\s*\(\s*|\s*\)\s*',elem_list[1].strip(' {}'))))
for point in points:
p = re.match(r'\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*', point).groups()
if 'points' not in measurement.keys():
measurement['points'] = []
measurement['points'].append(tuple(map(float,p)))
else:
values = list(filter(None, elem_list[1].strip(' {}').split(' ')))
for value in values:
if name not in measurement.keys():
measurement[name] = []
measurement[name].append(float(value))
return measurement
to_parse = '#10 points = { ( 2.96296 , 0.822213 ) ( 3.7037 , 0.902167 ) } ; L = { 5.20086 } ; P = { 3.14815 3.51852 } ;'
print(extract_line(to_parse))
You can do it using re.findall:
import re
to_parse = '#10 points = { ( 2.96296 , 0.822213 ) ( 3.7037 , 0.902167 ) } ; L = { 5.20086 } ; P = { 3.14815 3.51852 } ;'
m_list = re.findall(r'(\w+)\s*=\s*{([^}]*)}', to_parse)
measurements = {}
for k,v in m_list:
if k == 'points':
elts = re.findall(r'([0-9.]+)\s*,\s*([0-9.]+)', v)
measurements[k] = [tuple(map(float, elt)) for elt in elts]
else:
measurements[k] = [float(x) for x in v.split()]
print(measurements)
Feel free to put it in a function and to check if keys don't already exists.
This:
import re
a=re.findall(r' ([\d\.eE-]*) ',to_parse)
map(float, a)
>> [2.96296, 0.822213, 3.7037, 0.902167, 5.20086, 3.14815]
Will give you your list of numbers, is that what you look for?

Search for a value in a nested dictionary python

Search for a value and get the parent dictionary names (keys):
Dictionary = {dict1:{
'part1': {
'.wbxml': 'application/vnd.wap.wbxml',
'.rl': 'application/resource-lists+xml',
},
'part2':
{'.wsdl': 'application/wsdl+xml',
'.rs': 'application/rls-services+xml',
'.xop': 'application/xop+xml',
'.svg': 'image/svg+xml',
},
'part3':{...}, ...
dict2:{
'part1': { '.dotx': 'application/vnd.openxmlformats-..'
'.zaz': 'application/vnd.zzazz.deck+xml',
'.xer': 'application/patch-ops-error+xml',}
},
'part2':{...},
'part3':{...},...
},...
In above dictionary I need to search values like: "image/svg+xml". Where, none of the values are repeated in the dictionary. How to search the "image/svg+xml"? so that it should return the parent keys in a dictionary { dict1:"part2" }.
Please note: Solutions should work unmodified for both Python 2.7 and Python 3.3.
Here's a simple recursive version:
def getpath(nested_dict, value, prepath=()):
for k, v in nested_dict.items():
path = prepath + (k,)
if v == value: # found value
return path
elif hasattr(v, 'items'): # v is a dict
p = getpath(v, value, path) # recursive call
if p is not None:
return p
Example:
print(getpath(dictionary, 'image/svg+xml'))
# -> ('dict1', 'part2', '.svg')
To yield multiple paths (Python 3 only solution):
def find_paths(nested_dict, value, prepath=()):
for k, v in nested_dict.items():
path = prepath + (k,)
if v == value: # found value
yield path
elif hasattr(v, 'items'): # v is a dict
yield from find_paths(v, value, path)
print(*find_paths(dictionary, 'image/svg+xml'))
This is an iterative traversal of your nested dicts that additionally keeps track of all the keys leading up to a particular point. Therefore as soon as you find the correct value inside your dicts, you also already have the keys needed to get to that value.
The code below will run as-is if you put it in a .py file. The find_mime_type(...) function returns the sequence of keys that will get you from the original dictionary to the value you want. The demo() function shows how to use it.
d = {'dict1':
{'part1':
{'.wbxml': 'application/vnd.wap.wbxml',
'.rl': 'application/resource-lists+xml'},
'part2':
{'.wsdl': 'application/wsdl+xml',
'.rs': 'application/rls-services+xml',
'.xop': 'application/xop+xml',
'.svg': 'image/svg+xml'}},
'dict2':
{'part1':
{'.dotx': 'application/vnd.openxmlformats-..',
'.zaz': 'application/vnd.zzazz.deck+xml',
'.xer': 'application/patch-ops-error+xml'}}}
def demo():
mime_type = 'image/svg+xml'
try:
key_chain = find_mime_type(d, mime_type)
except KeyError:
print ('Could not find this mime type: {0}'.format(mime_type))
exit()
print ('Found {0} mime type here: {1}'.format(mime_type, key_chain))
nested = d
for key in key_chain:
nested = nested[key]
print ('Confirmation lookup: {0}'.format(nested))
def find_mime_type(d, mime_type):
reverse_linked_q = list()
reverse_linked_q.append((list(), d))
while reverse_linked_q:
this_key_chain, this_v = reverse_linked_q.pop()
# finish search if found the mime type
if this_v == mime_type:
return this_key_chain
# not found. keep searching
# queue dicts for checking / ignore anything that's not a dict
try:
items = this_v.items()
except AttributeError:
continue # this was not a nested dict. ignore it
for k, v in items:
reverse_linked_q.append((this_key_chain + [k], v))
# if we haven't returned by this point, we've exhausted all the contents
raise KeyError
if __name__ == '__main__':
demo()
Output:
Found image/svg+xml mime type here: ['dict1', 'part2', '.svg']
Confirmation lookup: image/svg+xml
Here is a solution that works for a complex data structure of nested lists and dicts
import pprint
def search(d, search_pattern, prev_datapoint_path=''):
output = []
current_datapoint = d
current_datapoint_path = prev_datapoint_path
if type(current_datapoint) is dict:
for dkey in current_datapoint:
if search_pattern in str(dkey):
c = current_datapoint_path
c+="['"+dkey+"']"
output.append(c)
c = current_datapoint_path
c+="['"+dkey+"']"
for i in search(current_datapoint[dkey], search_pattern, c):
output.append(i)
elif type(current_datapoint) is list:
for i in range(0, len(current_datapoint)):
if search_pattern in str(i):
c = current_datapoint_path
c += "[" + str(i) + "]"
output.append(i)
c = current_datapoint_path
c+="["+ str(i) +"]"
for i in search(current_datapoint[i], search_pattern, c):
output.append(i)
elif search_pattern in str(current_datapoint):
c = current_datapoint_path
output.append(c)
output = filter(None, output)
return list(output)
if __name__ == "__main__":
d = {'dict1':
{'part1':
{'.wbxml': 'application/vnd.wap.wbxml',
'.rl': 'application/resource-lists+xml'},
'part2':
{'.wsdl': 'application/wsdl+xml',
'.rs': 'application/rls-services+xml',
'.xop': 'application/xop+xml',
'.svg': 'image/svg+xml'}},
'dict2':
{'part1':
{'.dotx': 'application/vnd.openxmlformats-..',
'.zaz': 'application/vnd.zzazz.deck+xml',
'.xer': 'application/patch-ops-error+xml'}}}
d2 = {
"items":
{
"item":
[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{"id": "1001", "type": "Regular"},
{"id": "1002", "type": "Chocolate"},
{"id": "1003", "type": "Blueberry"},
{"id": "1004", "type": "Devil's Food"}
]
},
"topping":
[
{"id": "5001", "type": "None"},
{"id": "5002", "type": "Glazed"},
{"id": "5005", "type": "Sugar"},
{"id": "5007", "type": "Powdered Sugar"},
{"id": "5006", "type": "Chocolate with Sprinkles"},
{"id": "5003", "type": "Chocolate"},
{"id": "5004", "type": "Maple"}
]
},
...
]
}
}
pprint.pprint(search(d,'svg+xml','d'))
>> ["d['dict1']['part2']['.svg']"]
pprint.pprint(search(d2,'500','d2'))
>> ["d2['items']['item'][0]['topping'][0]['id']",
"d2['items']['item'][0]['topping'][1]['id']",
"d2['items']['item'][0]['topping'][2]['id']",
"d2['items']['item'][0]['topping'][3]['id']",
"d2['items']['item'][0]['topping'][4]['id']",
"d2['items']['item'][0]['topping'][5]['id']",
"d2['items']['item'][0]['topping'][6]['id']"]
Here are two similar quick and dirty ways of doing this type of operation. The function find_parent_dict1 uses list comprehension but if you are uncomfortable with that then find_parent_dict2 uses the infamous nested for loops.
Dictionary = {'dict1':{'part1':{'.wbxml':'1','.rl':'2'},'part2':{'.wbdl':'3','.rs':'4'}},'dict2':{'part3':{'.wbxml':'5','.rl':'6'},'part4':{'.wbdl':'1','.rs':'10'}}}
value = '3'
def find_parent_dict1(Dictionary):
for key1 in Dictionary.keys():
item = {key1:key2 for key2 in Dictionary[key1].keys() if value in Dictionary[key1][key2].values()}
if len(item)>0:
return item
find_parent_dict1(Dictionary)
def find_parent_dict2(Dictionary):
for key1 in Dictionary.keys():
for key2 in Dictionary[key1].keys():
if value in Dictionary[key1][key2].values():
print {key1:key2}
find_parent_dict2(Dictionary)
Traverses a nested dict looking for a particular value. When success is achieved the full key path to the value is printed. I left all the comments and print statements for pedagogical purposes (this isn't production code!)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jan 24 17:16:46 2022
#author: wellington
"""
class Tree(dict):
"""
allows autovivification as in Perl hashes
"""
def __missing__(self, key):
value = self[key] = type(self)()
return value
# tracking the key sequence when seeking the target
key_list = Tree()
# dict storing the target success result
success = Tree()
# example nested dict of dicts and lists
E = {
'AA':
{
'BB':
{'CC':
{
'DD':
{
'ZZ':'YY',
'WW':'PP'
},
'QQ':
{
'RR':'SS'
},
},
'II':
{
'JJ':'KK'
},
'LL':['MM', 'GG', 'TT']
}
}
}
def find_keys_from_value(data, target):
"""
recursive function -
given a value it returns all the keys in the path to that value within
the dict "data"
there are many paths and many false routes
at the end of a given path if success has not been achieved
the function discards keys to get back to the next possible path junction
"""
print(f"the number of keys in the local dict is {len(data)}")
key_counter = 0
for key in data:
key_counter += 1
# if target has been located stop iterating through keys
if success[target] == 1:
break
else:
# eliminate prior key from path that did not lead to success
if key_counter > 1:
k_list.pop()
# add key to new path
k_list.append(key)
print(f"printing k_list after append{k_list}")
# if target located set success[target] = 1 and exit
if key == target or data[key] == target:
key_list[target] = k_list
success[target] = 1
break
# if the target has not been located check to see if the value
# associated with the new key is a dict and if so return to the
# recursive function with the new dict as "data"
elif isinstance(data[key], dict):
print(f"\nvalue is dict\n {data[key]}")
find_keys_from_value(data[key], target)
# check to see if the value associated with the new key is a list
elif isinstance(data[key], list):
# print("\nv is list\n")
# search through the list
for i in data[key]:
# check to see if the list element is a dict
# and if so return to the recursive function with
# the new dict as "data
if isinstance(i, dict):
find_keys_from_value(i, target)
# check to see if each list element is the target
elif i == target:
print(f"list entry {i} is target")
success[target] = 1
key_list[target] = k_list
elif i != target:
print(f"list entry {i} is not target")
print(f"printing k_list before pop_b {k_list}")
print(f"popping off key_b {key}")
# so if value is not a key and not a list and not the target then
# discard the key from the key list
elif data[key] != target:
print(f"value {data[key]} is not target")
print(f"printing k_list before removing key_before {k_list}")
print(f"removing key_c {key}")
k_list.remove(key)
# select target values
values = ["PP", "SS", "KK", "TT"]
success = {}
for target in values:
print(f"\nlooking for target {target}")
success[target] = 0
k_list = []
find_keys_from_value(E, target)
print(f"\nprinting key_list for target {target}")
print(f"{key_list[target]}\n")
print("\n****************\n\n")

Convert a space-delimited tree to useful dict in python

I have an output (a list) of items, like such:
Root
Branch1
LeafA
LeafB
Branch2
LeafC
LeafZ
LeafD
They are all two-space delimited.
I want build a logical representation of this list without the leading spaces, and retain the parent-child relationshiop.
A final possible result:
aDict = {
'Root': null,
'Branch1': 'Root',
'LeafA': 'Branch1',
... so on and so forth
}
Ultimately, I want to iterate through the dictionary and retrieve the Key and parent, as well as another value from another dict based on Key.
Try this:
tree = """Root
Branch1
LeafA
LeafB
Branch2
LeafC
LeafZ
LeafD"""
aDict = {}
iDict = {}
for line in tree.split("\n"):
key = line.lstrip(" ")
indent = (len(line) - len(key)) / 2
if indent == 0:
aDict[key] = None
else:
aDict[key] = iDict[indent - 1]
iDict[indent] = key
print aDict
# {'LeafD': 'Branch2', 'LeafA': 'Branch1', 'Branch2': 'Root', 'LeafC': 'Branch2', 'LeafB': 'Branch1', 'Branch1': 'Root', 'Root': None, 'LeafZ': 'LeafC'}
I guess this solves the problem:
#!/usr/bin/env python
def f(txt):
stack = []
ret = {}
for line in txt.split('\n'):
a = line.split(' ')
level = len(a) - 1
key = a[-1]
stack = stack[:level]
ret[key] = stack[-1] if len(stack) > 0 else None
stack.append(key)
return ret
print f("""Root
Branch1
LeafA
LeafB
Branch2
LeafC
LeafZ
LeafD""")
print f("""Root1
Branch1
LeafA
LeftZ
Branch2
LeftB
Root2
Branch3""")
Output:
{'LeafD': 'Branch2', 'LeafA': 'Branch1', 'Branch2': 'Root', 'LeafC': 'Branch2', 'LeafB': 'Branch1', 'Branch1': 'Root', 'Root': None, 'LeafZ': 'LeafC'}
{'LeafA': 'Branch1', 'Branch2': 'Root1', 'Branch1': 'Root1', 'LeftZ': 'LeafA', 'LeftB': 'Branch2', 'Branch3': 'Root2', 'Root1': None, 'Root2': None}

Categories

Resources