Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine values of same keys in a list of dicts

Tags:

python

I have a list of dictionaries in the following format:

foo = [
    {'a': 'x', 'b': 'y', 'c': 'z'},
    {'a': 'j', 'c': 'z'}
]

I want to group this list of dictionaries into a single dictionary, like:

bar = {
    'a': ['x', 'j'],
    'b': ['y', None],
    'c': ['z', 'z']
}

What I've currently done is, looping through all the dicts in foo and create a list of keys and then looping again over the same to create bar. I wonder whether there is a simpler way to accomplish this. Can anyone help?

like image 511
akhilsp Avatar asked Aug 12 '17 10:08

akhilsp


Video Answer


2 Answers

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 :)

like image 180
Nayanexx.py Avatar answered Oct 10 '22 12:10

Nayanexx.py


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
like image 29
Alex Hall Avatar answered Oct 10 '22 12:10

Alex Hall