I have a dictionary containing lists of dictionaries and nested lists of strings. I figured out a way using comprehensions to perform checks before adding items. However, I'm not sure if this is the best, most simplified way to do this.
my_dict = {
'employees':[
{
'name':'Kevin',
'software':[
{
'name':'soft1',
'modules':[
'mod1',
'mod2',
'mod3'
]
},
{
'name':'soft2',
'modules':[
'mod1',
'mod2',
'mod3'
]
},
{
'name':'soft3',
'modules':[
'mod1',
'mod2',
'mod3'
]
}
]
},
{
'name':'Bob',
'software':[
{
'name':'soft3',
'modules':[
'mod4',
'mod5',
'mod6'
]
},
{
'name':'soft4',
'modules':[
'mod10'
]
},
{
'name':'soft6',
'modules':[
'mod1',
'mod5'
]
},
{
'name':'soft7',
'modules':[
'mod1',
'mod3',
'mod5'
]
}
]
}
]
}
new_employee_name = "Steward"
new_software_learnt = "soft2"
new_module_learnt = "mod20"
if not new_employee_name in [_['name'] for _ in my_dict['employees']]:
my_dict['employees'].append({'name':new_employee_name, 'software':[{"name":new_software_learnt, 'modules':[new_module_learnt]}]})
new_software_learnt = "soft3"
new_module_learnt = "mod22"
if not new_software_learnt in [_['name'] for _ in [_['software'] for _ in my_dict['employees']][[_['name'] for _ in my_dict['employees']].index(new_employee_name)]]:
my_dict['employees'][[_['name'] for _ in my_dict['employees']].index(new_employee_name)]['software'].append({'name':new_software_learnt, 'modules':[new_module_learnt]})
new_software_learnt = "soft3"
new_module_learnt = "mod55"
if not new_module_learnt in [_['modules'] for _ in [_['software'] for _ in my_dict['employees']][[_['name'] for _ in my_dict['employees']].index(new_employee_name)]][[_['name'] for _ in [_['software'] for _ in my_dict['employees']][[_['name'] for _ in my_dict['employees']].index(new_employee_name)]].index(new_software_learnt)]:
[_['modules'] for _ in [_['software'] for _ in my_dict['employees']][[_['name'] for _ in my_dict['employees']].index(new_employee_name)]][[_['name'] for _ in [_['software'] for _ in my_dict['employees']][[_['name'] for _ in my_dict['employees']].index(new_employee_name)]].index(new_software_learnt)].append(new_module_learnt)
print(my_dict['employees'])
Could anyone suggest a better more simplified approach? Perhaps there are some modules that are good in that? Should I better break down the comprehensions into separate functions to check each "level" of the dictionary?
Ultimately, this dictionary will be saved as json file.
As you suggest, moving the work into one or more helper functions will simplify your mainline code significantly. add_empdata()
should probably be refactored further, but here is a quick and dirty example of the general idea:
from pprint import pprint
def add_empdata(empdict, empname, swname, modname):
# find employee record if extant else create new employee record and exit
for employee in empdict["employees"]:
if employee["name"] == empname:
break
else: # no break
empdict["employees"].append(dict(name=empname, software=[dict(name=swname, modules=[modname])]))
return
# add software and module data for extant employee if not already in employee
for software in employee["software"]:
if software["name"] == swname:
if modname not in software["modules"]:
software["modules"].append(modname)
break
else: # no break
employee["software"].append(dict(name=swname, modules=[modname]))
new_empdata = [
("Steward", "soft2", "mod20"),
("Steward", "soft3", "mod22"),
("Steward", "soft3", "mod55"),
]
for empname, swname, modname in new_empdata:
add_empdata(my_dict, empname, swname, modname)
pprint(my_dict['employees'])
Output:
[{'name': 'Kevin',
'software': [{'modules': ['mod1', 'mod2', 'mod3'], 'name': 'soft1'},
{'modules': ['mod1', 'mod2', 'mod3'], 'name': 'soft2'},
{'modules': ['mod1', 'mod2', 'mod3'], 'name': 'soft3'}]},
{'name': 'Bob',
'software': [{'modules': ['mod4', 'mod5', 'mod6'], 'name': 'soft3'},
{'modules': ['mod10'], 'name': 'soft4'},
{'modules': ['mod1', 'mod5'], 'name': 'soft6'},
{'modules': ['mod1', 'mod3', 'mod5'], 'name': 'soft7'}]},
{'name': 'Steward',
'software': [{'modules': ['mod20'], 'name': 'soft2'},
{'modules': ['mod22', 'mod55'], 'name': 'soft3'}]}]