Combine values of same keys in a list of dicts

bar = {
    k: [d.get(k) for d in foo]
    for k in set().union(*foo)
}

Things to google:

  • python list comprehension
  • python dict comprehension
  • python star
  • python dict get
  • python set union

I am just going to complement Alex Hall solution here, so that it does not return a lot of "None" values:

def merge_dictionary_list(dict_list):
  return {
    k: [d.get(k) for d in dict_list if k in d] # explanation A
    for k in set().union(*dict_list) # explanation B
  }

Explanation:

  • The whole thing inside {} is a dictionary comprehension
  • Explanation A: Go through all elements in dictionary list and get values for current key k if the current dictionary (d) being evaluated actually has that key.

OBS: Without the if k in d expression there could be a bunch of None values appended to the arrays in case the list of dictionaries contains different types of keys.

  • Explanation B: gets all keys from list of dictionary and unite them distinctly by using set().union. After all we can only have distinct elements in set data structure.

If you want to do it the traditional way, just go with:

def merge_list_of_dictionaries(dict_list):
  new_dict = {}
  for d in dict_list:
    for d_key in d:
      if d_key not in new_dict:
        new_dict[d_key] = []
      new_dict[d_key].append(d[d_key])
  return new_dict

I think the first solution looks more elegant, but the second one is more legible/readable.

Kind Regards :)


I would do this in two steps:

  1. Collect all keys into a single iterable:

    >>> import operator
    >>> from functools import reduce
    >>> all_keys = reduce(operator.or_, (d.keys() for d in foo))
    >>> all_keys
    {'a', 'b', 'c'}
    
  2. Use a dict comprehension to create the desired result:

    >>> bar = {key: [d.get(key) for d in foo] for key in all_keys}
    >>> bar
    {'a': ['x', 'j'], 'b': ['y', None], 'c': ['z', 'z']}
    

Tags:

Python