Home > Mobile >  Convert a list of dict of [{str:int}, {str:int}, ... ] to a single dict of {str:int}
Convert a list of dict of [{str:int}, {str:int}, ... ] to a single dict of {str:int}

Time:02-16

Given a data-structure like this:

[{'a':1, 'b': 2}, {'c':3 }, {'a':4, 'c':9}, {'d':0}, {'d': 0, 'b':6}]

The goal is to parse the data to produce:

{'a': 2.5, 'b': 4, 'c': 6, 'd': 0}

by doing:

  • Accumulate the values for each unique key,
  • Average the values per key

What's a simple way to achieve the data munging as desired above?


I've tried the following and it works:

from collections import defaultdict


x = [{'a':1, 'b': 2}, {'c':3 }, {'a':4, 'c':9}, {'d':0}, {'d': 0, 'b':6}]

z = defaultdict(list)

for _ in x:
    for k, v in y.items():
        z[k].append(v)

output = {k:mean(v) for k,v in z.items()}

But is there a simpler way to achieve the same data-parsing? Maybe with collections.Counter or something?

CodePudding user response:

If you want something with counter you could count the keys and values separately and then build the average like this:

original = [{'a':1, 'b': 2}, {'c':3 }, {'a':4, 'c':9}, {'d':0}, {'d': 0, 'b':6}]

sum_counter = dict(sum([Counter(x) for x in original], Counter()))
count_counter = dict(sum([Counter(x.keys()) for x in original], Counter()))
final = {k: sum_counter.get(k,0)/count_counter[k] for k in count_counter}

print(final)

Output:

{'a': 2.5, 'b': 4.0, 'c': 6.0, 'd': 0.0}

CodePudding user response:

complicated one liner

def mean_of_values_for_each_key(data):
   return {k: mean(d.get(k, 0) for d in data if k in d) for k in set(k for d in data for k in d.keys())}
  • Related