Home > Back-end >  Sum the values of dictionaries inside a list where the keys are the same
Sum the values of dictionaries inside a list where the keys are the same

Time:02-28

I have 4 lists of dictionaries and each list contains 4 dictionaries. The lists look similar to this:

    A = [
     {'1': 150, '2': 160, '3': 140, '4': 110},
     {'1': 230, '2': 650, '3': 134, '4': 650},  
     {'1': 220, '2': 530, '3': 980, '4': 3450},  
     {'1': 150, '2': 160, '3': 440, '4': 110}]

    B = [
     {'1': 165, '2': 430, '3': 134, '4': 650},
     {'1': 64, '2': 650, '3': 345, '4': 340},  
     {'1': 220, '2': 650, '3': 340, '4': 134},  
     {'1': 150, '2': 160, '3': 234, '4': 2340}]

    C = [
     {'1': 678, '2': 430, '3': 134, '4': 650},
     {'1': 344, '2': 650, '3': 345, '4': 340},  
     {'1': 220, '2': 650, '3': 340, '4': 134},  
     {'1': 150, '2': 160, '3': 234, '4': 2340}]

    D = [
     {'1': 165, '2': 430, '3': 134, '4': 650},
     {'1': 64, '2': 650, '3': 345, '4': 340},  
     {'1': 220, '2': 650, '3': 340, '4': 134},  
     {'1': 150, '2': 160, '3': 234, '4': 1440}]

I would like to sum the values of the first dictionary of each list, where the keys are the same (so for key '1', then for '2', then for '3' and so on ...), together with the values of the first dictionary of the rest of the lists, without using Pandas.
Then do the same for the second, third and fourth dictionary.

The expected outcome should be 4 dictionaries, that maintain the order of the keys while summing up the values for the keys that are the same.

I have tried the piece of code below:

for i in range (4):
    dict1 = A[i]
    dict2 = B[i]
    dict3 = C[i]
    dict4 = D[i]
# adding the values with common key      
    Cdict = Counter(dict1)   Counter(dict2)   Counter(dict3)   Counter(dict4)
    print(Cdict)

But the problem is that the order of the keys is changing:

Counter({'3': 1443, '1': 1248, '2': 1111, '4': 709})
Counter({'1': 1544, '2': 1273, '4': 1204, '3': 1110})
Counter({'1': 5210, '3': 1273, '4': 1248, '2': 1141})
Counter({'2': 891, '1': 784, '3': 646, '4': 581})

CodePudding user response:

IIUC this is pretty straight forward. You just write a function to sum up all values per key. Then apply it to the transposed list of lists of dicts.

def sum_by_key(dicts):
    result = {}

    for d in dicts:
        for k, v in d.items():
            result[k] = result.get(k, 0)   v

    return result

lists_of_dicts = [[{1:2, 3:4}, {1:10, 2:9}], [{3:8, 2:4}, {3:1, 2:5}]]
result = [sum_by_key(dicts) for dicts in zip(*lists_of_dicts)]

print(result)

(lists_of_dicts would be [A, B, C, D] with your variables)

Output:

[{1: 2, 3: 12, 2: 4}, {1: 10, 2: 14, 3: 1}]

edit: with your new sample data

lists_of_dicts = [A, B, C, D]
result = [sum_by_key(dicts) for dicts in zip(*lists_of_dicts)]
print(result)

produces

[{'1': 1158, '2': 1450, '3': 542, '4': 2060}, {'1': 702, '2': 2600, '3': 1169, '4': 1670}, {'1': 880, '2': 2480, '3': 2000, '4': 3852}, {'1': 600, '2': 640, '3': 1142, '4': 6230}]

CodePudding user response:

I use numpy. And btw, I think the result you gave is incorrect, mine from the code below is:

results:
{'1': 1158, '2': 1450, '3': 542, '4': 2060}
{'1': 702, '2': 2600, '3': 1169, '4': 1670}
{'1': 880, '2': 2480, '3': 2000, '4': 3852}
{'1': 600, '2': 640, '3': 1142, '4': 6230}

import numpy as np

A = [
    {'1': 150, '2': 160, '3': 140, '4': 110},
    {'1': 230, '2': 650, '3': 134, '4': 650},
    {'1': 220, '2': 530, '3': 980, '4': 3450},
    {'1': 150, '2': 160, '3': 440, '4': 110}]

B = [
    {'1': 165, '2': 430, '3': 134, '4': 650},
    {'1': 64, '2': 650, '3': 345, '4': 340},
    {'1': 220, '2': 650, '3': 340, '4': 134},
    {'1': 150, '2': 160, '3': 234, '4': 2340}]

C = [
    {'1': 678, '2': 430, '3': 134, '4': 650},
    {'1': 344, '2': 650, '3': 345, '4': 340},
    {'1': 220, '2': 650, '3': 340, '4': 134},
    {'1': 150, '2': 160, '3': 234, '4': 2340}]

D = [
    {'1': 165, '2': 430, '3': 134, '4': 650},
    {'1': 64, '2': 650, '3': 345, '4': 340},
    {'1': 220, '2': 650, '3': 340, '4': 134},
    {'1': 150, '2': 160, '3': 234, '4': 1440}]

group_list = [A,B,C,D]
items_num = len(A)
results =  []

for i in range(items_num):
    cur_item_dict = dict()

    for key in A[0].keys():
        cur_item_dict[key] = np.sum([ls[i][key]  for j, ls in enumerate(group_list)])

    results.append(cur_item_dict)

print('results:')
for res in results:
print(res)
  • Related