-1

I have data in two separate objects of the same shape, and I want to add the values together. The issue is that each object is a dictionary of dictionaries of lists of dictionaries. I have provided an example of what it looks like below.

data1 = {
    'months': {
        'type1': [
            {'name': 'Month 1', 'value': 10, 'sequence': 1}, 
            {'name': 'Month 2', 'value': 20, 'sequence': 2}, 
            {'name': 'Month 3', 'value': 30, 'sequence': 3}
        ],
        'type2': [
            {'name': 'Month 1', 'value': 10, 'sequence': 1}, 
            {'name': 'Month 2', 'value': 20, 'sequence': 2}, 
            {'name': 'Month 3', 'value': 30, 'sequence': 3}
        ]
    },
    'years': {
        'type1': [
            {'name': 'Year 1', 'value': 10, 'sequence': 1},
            {'name': 'Year 2', 'value': 20, 'sequence': 2},
            {'name': 'Year 3', 'value': 30, 'sequence': 3}
        ],
        'type2': [
            {'name': 'Year 1', 'value': 10, 'sequence': 1},
            {'name': 'Year 2', 'value': 20, 'sequence': 2},
            {'name': 'Year 3', 'value': 30, 'sequence': 3}
        ]
    }
}

The above is a simplified version of what the actual data looks like. For sake of this example, let us say that data2 would be identical to data1 with regards to values. Note: they are identical with regards to shape.

I would like to be able to iterate over these nested dictionary/lists and add the values together for each month within each type, and maintain all other necessary information.

I.e. data1 + data2 = data_output (provided below).

data_output = {
    'months': {
        'type1': [
            {'name': 'Month 1', 'value': 20, 'sequence': 1}, 
            {'name': 'Month 2', 'value': 40, 'sequence': 2}, 
            {'name': 'Month 3', 'value': 60, 'sequence': 3}
        ],
        'type2': [
            {'name': 'Month 1', 'value': 20, 'sequence': 1}, 
            {'name': 'Month 2', 'value': 40, 'sequence': 2}, 
            {'name': 'Month 3', 'value': 60, 'sequence': 3}
        ]
    },
    'years': {
        'type1': [
            {'name': 'Year 1', 'value': 20, 'sequence': 1},
            {'name': 'Year 2', 'value': 40, 'sequence': 2},
            {'name': 'Year 3', 'value': 60, 'sequence': 3}
        ],
        'type2': [
            {'name': 'Year 1', 'value': 20, 'sequence': 1},
            {'name': 'Year 2', 'value': 40, 'sequence': 2},
            {'name': 'Year 3', 'value': 60, 'sequence': 3}
        ]
    }
}

I have tried applying the solutions listed in the following answers, but with no success (which may be due to my misunderstanding since I am new to Python):

Based on the above links, I understand that variations on this question have been asked before, but I cannot seem to make their solutions work for me, so any help with this would be greatly appreciated. Thank you!

jizhihaoSAMA
  • 12,336
  • 9
  • 27
  • 49
FitzKaos
  • 381
  • 3
  • 20
  • What specific code did you try to use? What was the problem with it? This is not a matter of luck. – mkrieger1 Jun 03 '20 at 15:46
  • 1
    Please see [ask], in particular please create a [mre]. Also [Why is “Can someone help me?” not an actual question?](https://meta.stackoverflow.com/questions/284236/why-is-can-someone-help-me-not-an-actual-question) – mkrieger1 Jun 03 '20 at 15:49
  • Apologies @mkrieger1 "with no luck" is idiomatic English which means "with no success"; I am not suggesting there is any luck involved. I will amend this. And I appreciate your link to the How to Ask. However, as you can see, I have provided a minimal reproducible example of the data, plus the exact desired output. I have also broken down exactly what I need to be summed together, and at no point did I say just "Someone help me". I, admittedly, have not provided all my failed attempts, since I believe that they would not be useful, especially since I am fairly new to Python. – FitzKaos Jun 03 '20 at 15:59

1 Answers1

1

Assuming your dictionaries have the same structure as the one you mentioned in your question, you can do something like the following (assuming data1 and data2 as input data):

import copy
data_out = copy.deepcopy(data1)

# months, years,...
for i in data_out:
    # type 1,2,3,...
    for j in data_out[i]:
        # tuples for months/years
        for k in range(len(data_out[i][j])):
            print(i,j,k)
            data_out[i][j][k]['value'] += data2[i][j][k]['value']

which produces the following data_out when data2=data1:

{
   "months":{
      "type1":[
         {
            "name":"Month 1",
            "value":20,
            "sequence":1
         },
         {
            "name":"Month 2",
            "value":40,
            "sequence":2
         },
         {
            "name":"Month 3",
            "value":60,
            "sequence":3
         }
      ],
      "type2":[
         {
            "name":"Month 1",
            "value":20,
            "sequence":1
         },
         {
            "name":"Month 2",
            "value":40,
            "sequence":2
         },
         {
            "name":"Month 3",
            "value":60,
            "sequence":3
         }
      ]
   },
   "years":{
      "type1":[
         {
            "name":"Year 1",
            "value":20,
            "sequence":1
         },
         {
            "name":"Year 2",
            "value":40,
            "sequence":2
         },
         {
            "name":"Year 3",
            "value":60,
            "sequence":3
         }
      ],
      "type2":[
         {
            "name":"Year 1",
            "value":20,
            "sequence":1
         },
         {
            "name":"Year 2",
            "value":40,
            "sequence":2
         },
         {
            "name":"Year 3",
            "value":60,
            "sequence":3
         }
      ]
   }
}

In case not all your dictionaries have the same format, you should put if statements checking the existence of the keys.

nima72
  • 36
  • 2
  • Thank you @nima72 - I think this should work. There is a slight difference that might require an `if` statement, but I will have a play around to see if it works. Thanks! – FitzKaos Jun 03 '20 at 16:17