Home > Mobile >  Merge key values in list of dictionaries
Merge key values in list of dictionaries

Time:12-08

I have a single list containing dictionaries:

start_queue = [{"ticket": "INC1", "vmname": "testapp01", "status": "online"},
               {"ticket": "INC2", "vmname": "demo02", "status": "remove"},
               {"ticket": "INC2", "vmname": "demo03", "status": "remove"},
               {"ticket": "INC2", "vmname": "demo04", "status": "remove"},
               {"ticket": "INC3", "vmname": "dev05", "status": "remove"},
               {"ticket": "INC3", "vmname": "dev06", "status": "remove"}]

I'm trying to combine the values to end up in this state:

final_queue = [{"ticket": "INC1", "vmname": ["testapp01"], "status": ["online"]},
               {"ticket": "INC2", "vmname": ["demo02","demo3","demo4"], "status": ["remove","remove","remove"]},
               {"ticket": "INC3", "vmname": ["dev05", "dev6"], "status": ["remove", "remove"]}]

I've looked into using a default dict like so:

tmp_dict = {}
for item in start_queue:
    tmp_dict.setdefault(item['ticket', []).append(item['vmname'])
final_queue = [{'ticket': k, 'vmname': v} for k,v in tmp_dict.items()}]

But .setdefault only takes two arguements and outputs two. I can't find a way to include my 'status' key/values. How can I merge this list to get my end result?

CodePudding user response:

itertools to the rescue:

from itertools import groupby

final_queue = []
for ticket, groups in groupby(start_queue, lambda d: d.get("ticket")):
    groups = list(groups)
    final_queue.append(
        {
            "ticket": ticket,
            "vmname": [group["vmname"] for group in groups],
            "status": [group["status"] for group in groups],
        }
    )

CodePudding user response:

Code:

final_queue =[]

for i in set([i['ticket'] for i in start_queue]):    ##{'INC1', 'INC2', 'INC3'}
    dic = {'ticket': i, 'vmname': [], 'status': []}  ##Creating empty teamplate
    for s in start_queue:                            ##Looping over list
        if s['ticket']==i:                           ##If ticket same as I
            for k in ['vmname', 'status']:           ##looping over dict list
                dic[k].append(s[k])                  ##append value by key
            
    final_queue.append(dic)                          ##append the whole new dic 
final_queue

Output:

[{'ticket': 'INC3',
  'vmname': ['dev05', 'dev06'],
  'status': ['remove', 'remove']},
 {'ticket': 'INC1', 'vmname': ['testapp01'], 'status': ['online']},
 {'ticket': 'INC2',
  'vmname': ['demo02', 'demo03', 'demo04'],
  'status': ['remove', 'remove', 'remove']}]

CodePudding user response:

this is an example how you can solve the task with pandas module:

import pandas as pd

pd.DataFrame(start_queue).groupby('ticket', as_index=False).agg(list).to_dict('records')

>>>
'''
[{'ticket': 'INC1', 'vmname': ['testapp01'], 'status': ['online']},
 {'ticket': 'INC2', 'vmname': ['demo02', 'demo03', 'demo04'], 'status': ['remove', 'remove', 'remove']},
 {'ticket': 'INC3', 'vmname': ['dev05', 'dev06'], 'status': ['remove', 'remove']}]
  • Related