norpa norpa - 2 months ago 7
Python Question

Creating a dictionary with multiple values per key from a list of dictionaries

I have the following list of dictionaries:

listofdics = [{'StrId': 11, 'ProjId': 1},{'StrId': 11,'ProjId': 2},
{'StrId': 22, 'ProjId': 3},{'StrId': 22, 'ProjId': 4},
{'StrId': 33, 'ProjId': 5},{'StrId': 33, 'ProjId': 6},
{'StrId': 34, 'ProjId': 7}]


I need to get all
ProjId
values for
StrId
that are duplicate. So this is the output I'm looking for:

new_listofdics = [{11:[1,2]}, {22:[3,4]}, {33:[5,6]], {34:[7]}]


I wrote a function that creates a list of dictionaries with
StrId
values as keys, and a list with all
ProjId
that share the same key as values. Here it is:

def compare_projids(listofdics):
proj_ids_dups = {}

for row in listofdics:
id_value = row['StrId']
proj_id_value = row['ProjId']
proj_ids_dups[id_value]=proj_id_value

if row['StrId'] == id_value:
sum_ids = []
sum_ids.append(proj_id_value)
proj_ids_dups[id_value]=sum_ids
return proj_ids_dups


This is the output I get now:

new_listofdics= {33: [6], 34: [7], 11: [2], 22: [4]}


What I see is that
append
replaces each
ProjId
value with the last one iterated, instead of adding them at the end of the list.

How can I fix this?...

Answer

It's unclear why you need to have such output new_listofdics = [{11:[1,2]}, {22:[3,4]}, {33:[5,6]], {34:[7]}], because it's better to have just dict object.

So program would look like this

>>> from collections import defaultdict
>>> listofdics = [{'StrId': 11, 'ProjId': 1},{'StrId': 11,'ProjId': 2},
              {'StrId': 22, 'ProjId': 3},{'StrId': 22, 'ProjId': 4},
              {'StrId': 33, 'ProjId': 5},{'StrId': 33, 'ProjId': 6},
              {'StrId': 34, 'ProjId': 7}]
>>> output = defaultdict(list)
>>> for item in listofdics:
...     output[item.get('StrId')].append(item.get('ProjId'))
>>> dict(output)
{11: [1, 2], 22: [3, 4], 33: [5, 6], 34: [7]}

It's much easier to go through that dict that your desired output.