jiwon Seo
jiwon Seo

Reputation: 23

How do you combine lists of multiple dictionaries in Python?

I'd like to merge a list of dictionaries with lists as values. Given

arr[0] = {'number':[1,2,3,4], 'alphabet':['a','b','c']}
arr[1] = {'number':[3,4], 'alphabet':['d','e']}
arr[2] = {'number':[6,7], 'alphabet':['e','f']}

the result I want would be

merge_arr = {'number':[1,2,3,4,3,4,6,7,], 'alphabet':['a','b','c','d','e','e','f']}

could you recommend any compact code?

Upvotes: 1

Views: 2192

Answers (4)

hugo
hugo

Reputation: 3241

EDIT: As noted by @pault, the solution below is of quadratic complexity, and therefore not recommended for large lists. There are more optimal ways to go around it.

However if you’re looking for compactness and relative simplicity, keep reading.


If you want a more functional form, this two-liner will do:

arr = [{'number':[1,2,3,4], 'alphabet':['a','b','c']},{'number':[3,4], 'alphabet':['d','e']},{'number':[6,7], 'alphabet':['e','f']}]

keys = ['number', 'alphabet']
merge_arr = {key: reduce(list.__add__, [dict[key] for dict in arr]) for key in keys}

print arr

Outputs:

{'alphabet': ['a', 'b', 'c', 'd', 'e', 'e', 'f'], 'number': [1, 2, 3, 4, 3, 4, 6, 7]}

This won't merge recursively.

If you want it to work with arbitrary keys, not present in each dict, use:

keys = {k for k in dict.keys() for dict in arr}
merge_arr = {key: reduce(list.__add__, [dict.get(key, []) for dict in arr]) for key in keys}

Upvotes: 0

Rory Daulton
Rory Daulton

Reputation: 22544

Here is code that uses defaultdict to more easily collect the items. You could leave the result as a defaultdict but this version converts that to a regular dictionary. This code will work with any keys, and the keys in the various dictionaries can differ, as long as the values are lists. Therefore this answer is more general than the other answers given so far.

from collections import defaultdict

arr = [{'number':[1,2,3,4], 'alphabet':['a','b','c']},
       {'number':[3,4], 'alphabet':['d','e']},
       {'number':[6,7], 'alphabet':['e','f']},
]

merge_arr_default = defaultdict(list)
for adict in arr:
    for key, value in adict.items():
        merge_arr_default[key].extend(value)
merge_arr = dict(merge_arr_default)

print(merge_arr)

The printed result is

{'number': [1, 2, 3, 4, 3, 4, 6, 7], 'alphabet': ['a', 'b', 'c', 'd', 'e', 'e', 'f']}

Upvotes: 0

ncica
ncica

Reputation: 7206

arr = [{'number':[1,2,3,4], 'alphabet':['a','b','c']},{'number':[3,4], 'alphabet':['d','e']},{'number':[6,7], 'alphabet':['e','f']}]

dict = {}
for k in arr[0].keys():
    dict[k] = sum([dict[k] for dict in arr], [])
print (dict)

output:

{'number': [1, 2, 3, 4, 3, 4, 6, 7], 'alphabet': ['a', 'b', 'c', 'd', 'e', 'e', 'f']}

Upvotes: 1

Diptangsu Goswami
Diptangsu Goswami

Reputation: 5965

If you know these are the only keys in the dict, you can hard code it. If it isn't so simple, show a complicated example.

from pprint import pprint


arr = [
    {
        'number':[1,2,3,4], 
        'alphabet':['a','b','c']
    },
    {
        'number':[3,4], 
        'alphabet':['d','e']
    },
    {
        'number':[6,7], 
        'alphabet':['e','f']
    }
]

merged_arr = {
    'number': [],
    'alphabet': []
}

for d in arr:
    merged_arr['number'].extend(d['number'])
    merged_arr['alphabet'].extend(d['alphabet'])

pprint(merged_arr)

Output:

{'alphabet': ['a', 'b', 'c', 'd', 'e', 'e', 'f'],
 'number': [1, 2, 3, 4, 3, 4, 6, 7]}

Upvotes: 2

Related Questions