Given two list of dictionaries:
students = [
{"id": 1, "name": "A"},
{"id": 2, "name": "B"},
{"id": 99, "name": "C"},
{"id": 4, "name": "D"},
{"id": 101, "name": "E"},
]
classes = [
{"id": 1, "students": [1, 99]},
{"id": 2, "students": [1, 99, 101, 4]},
{"id": 3, "students": [4, 101]},
]
The classes
list has dictionaries with a students
key, the values of this key is also a list for example [1, 99]
for the first dict {"id": 1, "students": [1, 99]}
of classes
. I would like to replace these numbers [1,99]
with the dictionary from students
whenever the id
key in students
match with the integer present in the key students
.
For example, the first result would be : {"id": 1, "students": [{"id": 1, "name": "A"}, {"id": 99, "name": "C"}]}
.
Here is my attempt but I'm not getting it right:
d = defaultdict(dict)
for l in (students, classes):
for elem in l:
d[elem['id']].update(elem)
l3 = d.values()
print(l3)
CodePudding user response:
Create a mapping id
-> student dict. This way we can map id
s present in classes['student']
to corresponding student dict.
id_to_student = {dct["id"]: dct for dct in students}
# {1: {'id': 1, 'name': 'A'},
# 2: {'id': 2, 'name': 'B'},
# 99: {'id': 99, 'name': 'C'},
# 4: {'id': 4, 'name': 'D'},
# 101: {'id': 101, 'name': 'E'}}
# Now update `classes` dict
for dct in classes:
dct['students'] = [id_to_student[idx] for idx in dct['students']]
# [{'id': 1, 'students': [{'id': 1, 'name': 'A'}, {'id': 99, 'name': 'C'}]},
# {'id': 2, 'students': [{'id': 1, 'name': 'A'}, {'id': 99, 'name': 'C'}, {'id': 101, 'name': 'E'}, {'id': 4, 'name': 'D'}]},
# {'id': 3, 'students': [{'id': 4, 'name': 'D'}, {'id': 101, 'name': 'E'}]}]
CodePudding user response:
I've created an empty list new_classes
to store the results in. Then I have iterated through each dict in the classes
list. For each dict, I get the list in students using ids = dic['students']
, then I use list comprehension to go thorugh each dict in students and check if the id matches one of the ids in the list, and if so keep it ([i for i in students if i['id'] in ids]
) and replace the 'students' vale in that dict with the result. Then I append the whole updated dict to the new list. Full code:
new_classes = []
for dic in classes:
ids = dic['students']
dic['students'] = [i for i in students if i['id'] in ids]
new_classes.append(dic)
Output:
[{'id': 1, 'students': [{'id': 1, 'name': 'A'}, {'id': 99, 'name': 'C'}]},
{'id': 2,
'students': [{'id': 1, 'name': 'A'},
{'id': 99, 'name': 'C'},
{'id': 4, 'name': 'D'},
{'id': 101, 'name': 'E'}]},
{'id': 3, 'students': [{'id': 4, 'name': 'D'}, {'id': 101, 'name': 'E'}]}]
CodePudding user response:
Maybe something like this
from copy import deepcopy
from pprint import pprint
students = [
{"id": 1, "name": "A"},
{"id": 2, "name": "B"},
{"id": 99, "name": "C"},
{"id": 4, "name": "D"},
{"id": 101, "name": "E"},
]
classes = [
{"id": 1, "students": [1, 99]},
{"id": 2, "students": [1, 99, 101, 4]},
{"id": 3, "students": [4, 101]},
]
_classes = deepcopy(classes)
for idx, classe in enumerate(classes):
_classes[idx]['students'] = []
for i in classe['students']:
student = [x for x in students if x.get('id') == i]
_classes[idx]['students'].append(student[0])
classes = _classes
pprint(classes)
Result
[{'id': 1, 'students': [{'id': 1, 'name': 'A'}, {'id': 99, 'name': 'C'}]},
{'id': 2,
'students': [{'id': 1, 'name': 'A'},
{'id': 99, 'name': 'C'},
{'id': 101, 'name': 'E'},
{'id': 4, 'name': 'D'}]},
{'id': 3, 'students': [{'id': 4, 'name': 'D'}, {'id': 101, 'name': 'E'}]}]