I am trying to extract values from a list and populate it in a nested dictionary.
Input:
['abc-bcd_10_01_physics_90_70_20',
'abc-bcd_10_01_chemistry_85_75_10',
'ac-bd_10_03_biology_60_50_10',
'ad-bcd_10_05_physics_70_50_20',
'ac-bd_10_03_physics_65_50_15']
Expected Output:
[
{'first-name' : 'abc',
'last-name' : 'bcd',
'class' : '10',
'roll-number' : 1,
'marks' : [{'subject':'physics',
'total' : 90,
'theory' : 70,
'practical' : 20},
{'subject':'chemistry',
'total' : 85,
'theory' : 75,
'practical' : 10}]
},
{'first-name' : 'ac',
'last-name' : 'bd',
'class' : '10',
'roll-number' : 3,
'marks' : [{'subject':'biology',
'total' : 60,
'theory' : 50,
'practical' : 10},
{'subject':'physics',
'total' : 65,
'theory' : 50,
'practical' : 15},
]
},
{'first-name' : 'ad',
'last-name' : 'bcd',
'class' : '10',
'roll-number' : 5,
'marks' : [{'subject':'physics',
'total' : 70,
'theory' : 50,
'practical' : 20}]
}
]
I am able to extract values from the input list using split function and populate it in a plain dictionary, but stuck at the point where I need to group by the keys first-name,last-name,class,roll-number and collect the list of other keys under a common key called marks.
Also, I need the keys inside the dictionaries to be in the same order as specified above.
To group the subject scores by name, class and roll number, you need to build a dictionary with those values as the key (I've made one by joining them with #
, a string I assume cannot occur in class
or roll number
), and then push each subject into an array of marks. Once you have iterated over all the input, use dict.values
to convert to a list of dictionaries:
from collections import defaultdict
marks = ['abc-bcd_10_01_physics_90_70_20',
'abc-bcd_10_01_chemistry_85_75_10',
'ac-bd_10_03_biology_60_50_10',
'ad-bcd_10_05_physics_70_50_20',
'ac-bd_10_03_physics_65_50_15']
results = defaultdict(dict)
for m in marks:
name, classn, roll, subject, total, theory, practical = m.split('_')
fn, ln = name.split('-')
key = '#'.join([name, classn, roll])
if key not in results:
results[key] = { 'first_name' : fn,
'last_name' : ln,
'class' : classn,
'roll' : int(roll),
'marks' : []
}
results[key]['marks'].append({ 'subject' : subject,
'total' : int(total),
'theory' : int(theory),
'practical' : int(practical)
})
results = list(results.values())
print(results)
Output:
[
{'first_name': 'abc',
'last_name': 'bcd',
'class': '10',
'roll': 1,
'marks': [{'subject': 'physics', 'total': 90, 'theory': 70, 'practical': 20},
{'subject': 'chemistry', 'total': 85, 'theory': 75, 'practical': 10}
]
},
{'first_name': 'ac',
'last_name': 'bd',
'class': '10',
'roll': 3,
'marks': [{'subject': 'biology', 'total': 60, 'theory': 50, 'practical': 10},
{'subject': 'physics', 'total': 65, 'theory': 50, 'practical': 15}
]
},
{'first_name': 'ad',
'last_name': 'bcd',
'class': '10',
'roll': 5,
'marks': [{'subject': 'physics', 'total': 70, 'theory': 50, 'practical': 20}
]
}
]