Can anyone please help me to shorten the code and also to print the exact same output as the keys and values may vary every time it runs.
This is the input dictionary:
personal_info_list = [
{"id": 1, "name": "John", "age": 32, "cars": "BMW"},
{"id": 1, "title": "engineer", "cars": "Mercedes", "phone": "samsung"},
{"id": 1, "cars": "Jaguar", "phone": "iphone"},
{"id": 2, "name": "Charlie", "age": 22, "phone": "iphone"},
{"id": 2, "title": "doctor", "cars": "BMW", "phone": "samsung"},
{"id": 3, "name": "Michael", "cars": "Volkswagen", "phone": "nokia"},
{"id": 3, "title": "doctor", "cars": "BMW", "phone": "samsung"},
]
The output dictionary should be like:
{
1: {'name': 'John', 'age': 32, 'cars': ['BMW', 'Mercedes', 'Jaguar'], 'title': 'engineer', 'phone': ['samsung', 'iphone']},
2: {'name': 'Charlie', 'age': 22, 'phone': ['iphone', 'samsung'], 'title': 'doctor', 'cars': 'BMW'},
3: {'name': 'Michael', 'cars': ['Volkswagen', 'BMW'], 'phone': ['nokia', 'samsung'], 'title': 'doctor'}
}
I tried the code to get the all keys of Ids and Merge it with the rest of the dicts:
def formatDictionary(lst_1):
dict1={}
for i in lst_1:
for j in lst_1:
temp=[]
if i['id'] == j['id']:
for k,v in i.items():
S = Merge(i,j)
dict1[i['id']] = S
print(dict1)
formatDictionary(info_list)
Which gave me the output as:
{
1: {'id': 1, 'cars': 'Jaguar', 'phone': 'iphone'},
2: {'id': 2, 'title': 'doctor', 'cars': 'BMW', 'phone': 'samsung'},
3: {'id': 3, 'title': 'doctor', 'cars': 'BMW', 'phone': 'samsung'}
}
CodePudding user response:
Try using itertools.groupby
to get all dictionaries with the same id:
from itertools import groupby
from operator import itemgetter
result = {}
for personal_id, group in groupby(personal_info_list, itemgetter('id')):
result[personal_id] = {'id': personal_id}
for dct in group:
for k, v in dct.items():
if k != 'id':
if k in result[personal_id]:
if not isinstance(result[personal_id][k], list):
result[personal_id][k] = [result[personal_id][k]]
result[personal_id][k].append(v)
else:
result[personal_id][k] = v
Here is what result
looks like:
{1: {'age': 32,
'cars': ['BMW', 'Mercedes', 'Jaguar'],
'id': 1,
'name': 'John',
'phone': ['samsung', 'iphone'],
'title': 'engineer'},
2: {'age': 22,
'cars': 'BMW',
'id': 2,
'name': 'Charlie',
'phone': ['iphone', 'samsung'],
'title': 'doctor'},
3: {'cars': ['Volkswagen', 'BMW'],
'id': 3,
'name': 'Michael',
'phone': ['nokia', 'samsung'],
'title': 'doctor'}}
CodePudding user response:
Here is an alternative implementation.
#take the possible IDs
ids = set([d['id'] for d in personal_info_list])
r = {}
for _id in ids: #loop over the IDs and build a new dict
for d in personal_info_list:
if d['id'] != _id: #skip if not of interest
continue
if _id not in r: #init a sub-dict
r[_id] = {}
for k,v in d.items(): #populate the dict
if k in r[_id]:
if type(r[_id][k]) is str: #make list pf values if needed
r[_id][k] = [r[_id][k]]
if type(r[_id][k]) is list:
r[_id][k].append(v)
else:
r[_id][k] = v
r
will be
{1: {'id': 1,
'name': 'John',
'age': 32,
'cars': ['BMW', 'Mercedes', 'Jaguar'],
'title': 'engineer',
'phone': ['samsung', 'iphone']},
2: {'id': 2,
'name': 'Charlie',
'age': 22,
'phone': ['iphone', 'samsung'],
'title': 'doctor',
'cars': 'BMW'},
3: {'id': 3,
'name': 'Michael',
'cars': ['Volkswagen', 'BMW'],
'phone': ['nokia', 'samsung'],
'title': 'doctor'}}