Home > database >  Concat the values into a list to a key in python
Concat the values into a list to a key in python

Time:04-22

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'}}
  • Related