Merge key values in list of dictionaries

Question:

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?

Asked By: itinneed2022_1

||

Answers:

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']}]
Answered By: R. Baraiya

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],
        }
    )
Answered By: Tomer Ariel
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.