Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I merge a list of dicts into a single dict?

People also ask

How do I combine multiple Dicts?

Python 3.9 has introduced the merge operator (|) in the dict class. Using the merge operator, we can combine dictionaries in a single line of code. We can also merge the dictionaries in-place by using the update operator (|=).

Can you combine a list and a dictionary in Python?

Combining Lists and Dictionaries in Python¶ We have seen that combining the two data structures of lists and dictionaries can be done to represent complex arrangements of data.

How do I convert a list to a dictionary in Python?

Since python dictionary is unordered, the output can be in any order. To convert a list to dictionary, we can use list comprehension and make a key:value pair of consecutive elements. Finally, typecase the list to dict type.


This works for dictionaries of any length:

>>> result = {}
>>> for d in L:
...    result.update(d)
... 
>>> result
{'a':1,'c':1,'b':2,'d':2}

As a comprehension:

# Python >= 2.7
{k: v for d in L for k, v in d.items()}

# Python < 2.7
dict(pair for d in L for pair in d.items())

In case of Python 3.3+, there is a ChainMap collection:

>>> from collections import ChainMap
>>> a = [{'a':1},{'b':2},{'c':1},{'d':2}]
>>> dict(ChainMap(*a))
{'b': 2, 'c': 1, 'a': 1, 'd': 2}

Also see:

  • What is the purpose of collections.ChainMap?

This is similar to @delnan but offers the option to modify the k/v (key/value) items and I believe is more readable:

new_dict = {k:v for list_item in list_of_dicts for (k,v) in list_item.items()}

for instance, replace k/v elems as follows:

new_dict = {str(k).replace(" ","_"):v for list_item in list_of_dicts for (k,v) in list_item.items()}

unpacks the k,v tuple from the dictionary .items() generator after pulling the dict object out of the list


Little improvement for @dietbuddha answer with dictionary unpacking from PEP 448, for me, it`s more readable this way, also, it is faster as well:

from functools import reduce
result_dict = reduce(lambda a, b: {**a, **b}, list_of_dicts)

But keep in mind, this works only with Python 3.5+ versions.


For flat dictionaries you can do this:

from functools import reduce
reduce(lambda a, b: dict(a, **b), list_of_dicts)

>>> L=[{'a': 1}, {'b': 2}, {'c': 1}, {'d': 2}]    
>>> dict(i.items()[0] for i in L)
{'a': 1, 'c': 1, 'b': 2, 'd': 2}

Note: the order of 'b' and 'c' doesn't match your output because dicts are unordered

if the dicts can have more than one key/value

>>> dict(j for i in L for j in i.items())

dict1.update( dict2 )

This is asymmetrical because you need to choose what to do with duplicate keys; in this case, dict2 will overwrite dict1. Exchange them for the other way.

EDIT: Ah, sorry, didn't see that.

It is possible to do this in a single expression:

>>> from itertools import chain
>>> dict( chain( *map( dict.items, theDicts ) ) )
{'a': 1, 'c': 1, 'b': 2, 'd': 2}

No credit to me for this last!

However, I'd argue that it might be more Pythonic (explicit > implicit, flat > nested ) to do this with a simple for loop. YMMV.