ThinkTeamwork
ThinkTeamwork

Reputation: 594

How to convert this lists of dicts to a new dict

I wanna convert this list of dicts:

input_list = [
    {'a': 5,'b': 7},
    {'a': 3,'b': 4},
]

to this:

result_dict = {
    'a': [5, 3],
    'b': [7, 4]
}

I somehow can't manage to do this.

Can someone help me out there please.

Upvotes: 1

Views: 96

Answers (6)

RoadRunner
RoadRunner

Reputation: 26315

A slightly more verbose solution but this also works:

from itertools import groupby
from itertools import chain
from operator import itemgetter

input_list = [
    {'a': 5,'b': 7},
    {'a': 3,'b': 4},
]

all_lsts = sorted(chain.from_iterable(d.items() for d in input_list))

group = dict((k, list(map(itemgetter(1), g))) for _, g in groupby(all_lsts, key=itemgetter(0)))

print(group)
# {'a': [3, 5], 'b': [4, 7]}

Upvotes: 0

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476709

A vanilla Python approach

result = {}
for subdic in data:
    for k, v in subdic.items():
        result.setdefault(k, []).append(v)

Here we iterate over the items and we add an empty list to the result dict in case the key is not yet in the dictionary. Regardless whether there was already a list, we append v to that list.

Using defaultdict

We can make it more elegant by using defaultdict from collections:

from collections import defaultdict

result = defaultdict(list)
for subdic in data:
    for k, v in subdic.items():
        result[k].append(v)

Here we basically make abstraction of the setdefault (and we also save on constructing useless empty lists). In case the output should be a dict (and not a defaultdict), we can end the function with:

result = dict(result)

Using pandas

If every dictionary contains the same keys, we can use pandas:

from pandas import DataFrame

result = DataFrame(data).to_dict(orient='list')

Upvotes: 6

Elmex80s
Elmex80s

Reputation: 3504

One-liner

{y[0][0]: list(zip(*y)[1]) for y in zip(*[x.items() for x in input_list])}

A bit risky, we heavily rely on .items() returning keys in the same order each time.

Upvotes: 1

Michael H.
Michael H.

Reputation: 3483

In [1]: input_list = [
   ...:     {'a': 5,'b': 7},
   ...:     {'a': 3,'b': 4},
   ...: ]

In [2]: result_dict = {}

In [3]: for d in input_list:
   ...:     for k, v in d.items():
   ...:         if k not in result_dict:
   ...:             result_dict[k] = [v]
   ...:         else:
   ...:             result_dict[k].append(v)
   ...:             

In [4]: result_dict
Out[4]: {'a': [5, 3], 'b': [7, 4]}

Upvotes: 2

Ilija
Ilija

Reputation: 1604

So here is something that might help you.

It uses defaultdict construct and that might be an overkill, but it cleanly solves the task.

from collections import defaultdict

input_list = [
    {'a': 5, 'b': 7},
    {'a': 3, 'b': 4},
]

result_dict = defaultdict(list)

for i, j in zip(*[i.items() for i in input_list]):
    result_dict[i[0]].append(i[1])
    result_dict[j[0]].append(j[1])

print dict(result_dict)

Upvotes: 2

ThinkTeamwork
ThinkTeamwork

Reputation: 594

result_dict = {}
for index, row_dict in enumerate(input_list):
    for key, item_dict in row_dict.items():
        if not key in result_dict:
            result_dict[key] = []

        result_dict[key].append(row_dict[key])

hmm I think this does it. maybe someone comes up with a better approach..

Upvotes: 2

Related Questions