Manipulating some values in a nested dictionaries with use of lists in different ranges

I am intending to change change some specified values in a nested dictionary using list which have different range of elements. My try is to use loop for that.
here is the dictionary I want to change:

created_dataset [0] = { "Region 1" : { "commnet ": " Approved "},

                                     { " exchanges" :   { 'amount': 1.0,
                                                           'type': 'production',
                                                           'product': 'low-alloyed',
                                                           'name': 'market for steel',
                                                           'unit': 'kilogram',
                                                           'location': 'Region 1',
                                                           'database': 'ecoinvent'},

                                                         { 'amount': 0.378,                                   
                                                           'type': 'technosphere',
                                                           'product': 'low-alloyed',
                                                           'name': 'EAF',
                                                           'unit': 'kilogram',
                                                           'location': 'Region 1',                                 
                                                           'database': 'ecoinvent'},

                                                         { 'amount': 0.09,                        
                                                            'type': 'technosphere',
                                                            'product': 'low-alloyed',
                                                            'name': 'BOF', 
                                                            'unit': 'kilogram',
                                                            'location': 'Region 1',  
                                                            'database': 'Steel'}, 

                       { "Region 2" : { "commnet ": " Not Approved "},

                                      { " exchanges" :  { 'amount': 1.0,
                                                          'type': 'production',
                                                          'product': 'low-alloyed',
                                                          'name': 'market for steel',
                                                          'unit': 'kilogram',
                                                          'location': 'Region 1',
                                                          'database': 'ecoinvent'},

                                                        { 'amount': 0.378,                                   
                                                          'type': 'technosphere',
                                                           'product': 'low-alloyed',
                                                           'name': 'EAF',
                                                           'unit': 'kilogram',
                                                           'location': 'Region 1',                                 
                                                           'database': 'ecoinvent'},

                                                         { 'amount': 0.09,                        
                                                           'type': 'technosphere',
                                                           'product': 'low-alloyed',
                                                           'name': 'BOF', 
                                                           'unit': 'kilogram',
                                                           'location': 'Region 1',  
                                                           'database': 'Steel'}  }
                                                           }

I am intend to loop through some inner keys and change their values to from lists below:.

 Regions     = [ 'Region 1' , 'Region 2']
 Productions = ['Technology 1' , 'Technology 2','Technology 3','Technology 4']
 Amounts_Region1     = [x1, x2, x3, x4]
 Amounts_Region2     = [y1, y2, y3, y4]

to change the values for name of production technologies as for ‘name’ to those in Productions list if 'type'== 'technosphere' and also change the value ‘amount’ to those in Amounts_Region list respectively for Region 1 and Region 2.

(amount in Region 1 for Technology 1 = x1 , in Region 2 for Technology 1 = y1 , and so on like this)

My try is as below:

for r in Regions:
    for i in range (len(created_dataset[0]["r"]['exchanges']):
        if created_dataset[0]["r"]['exchanges'][i]['type'] == 'technosphere':
           for a in range (len (Productions):
              created_dataset[0]["r"]['exchanges'][i]['name'] = Productions[a]
                  for x in range (len( Amounts_Region1):                           # and same loop as for Region 2
                       created_dataset[0]["Region 1"]['exchanges'][i]['amount'] = Amounts_Region1[x]

Unfortunately, this won’t lead to what I expect cause the range of lists indexes are not equal and only when they have same number of elements, will run.

I would appreciate any help and suggestion to solve this issue

It’s maybe not the answer that you’re looking for, but my take on this is: if I had dictionaries nested that deep, I’d question the entire data structure! There has got to be a better way than that, don’t you think?

Absolutely! but unfortunately, this is not the structure that I developed. I am only responsible to apply the changes as I mentioned on that. Since the structure is much bigger than the sample I provided here, to me only looping makes sense, which unfortunately I am not able to figure out how would be the best approach for that.

So, on first glance, the problem seems to be here:
… len(created_dataset[0][“r”] …

You are submitting the string “r” to the dictionary, but what you should submit is the content of r.

Try this:

for r in Regions:
for i in range (len(created_dataset[0][r][‘exchanges’]):

In addition to the contribution by @RetoSchoelly I note that…

In the created_dataset [0] there are keys named " exchanges" which is not the same as the ['exchanges'] that you have in your for r in Regions loop. n.b: the space at the beginning.

I could be wrong, in so much as this makes no difference with this dataset, as it seems to be a Pandas (?) object, or the likes of, with which I have no experience.

@RetoSchoelly, @rob42 ,

Thank you very much for your corrections. the actual problem comes from there that my original database has 13 outer keys, referred to 13 regions and for inner key “exchanges” there are also 13 elements in the list with this sample structure :

{ 'amount': 0.378,                                   
   'type': 'technosphere',
   'product': 'low-alloyed',
    'name': 'EAF',
    'unit': 'kilogram',
    'location': 'Region 1',                                 
    'database': 'ecoinvent'}

however my lists for new value modification have 8 elements and the looping seems not work cause of index range incompatibility. to over come the problem I thought of emptying the value for “exchanges” like so:

for r in Regions:
    created_dataset[0][r]['exchanges'] = None

and now I am trying to create the same structure of values like:

Market = []
for r in Regions:
    for i in range(len(Productions )):   # in this example here to create 4 such dictionaries 
            new_exc = [{
                    "uncertainty type": 0,
                    "amount":Amounts_Region1[i],   # the condition : Amounts_Region1[i] if r == "Region 1" else Amount_ Region2[i]  !
                    "type": "technosphere",
                    "production volume": 1,
                    "product": "steel, low-alloyed",
                    "name": Productions[i],
                    "unit": "kilogram",
                    "location": r,
                    }]
            
            Market.extend(new_exc)
               

This piece of code is not consistent since I want to loop through each region but I don’t know how can I allocate the amounts for Region 1 to list Amount_Region 1 and for Region 2 in the same fashion but in same line.
the output is :

[{'uncertainty type': 0,
  'amount': x1,                 
  'type': 'technosphere',
  'production volume': 1,
  'product': 'steel, low-alloyed',
  'name': 'Technology 1',       
  'unit': 'kilogram',            
  'location': 'Region 1'},

{'uncertainty type': 0,
  'amount': x2,                  
  'type': 'technosphere',
  'production volume': 1,
  'product': 'steel, low-alloyed',
  'name': 'Technology 2',       
  'unit': 'kilogram',            
  'location': 'Region 2'},

{'uncertainty type': 0,
  'amount': x3,                 
  'type': 'technosphere',
  'production volume': 1,
  'product': 'steel, low-alloyed',
  'name': 'Technology 3',       
  'unit': 'kilogram',            
  'location': 'Region 1'},

{'uncertainty type': 0,
  'amount': x4,                 
  'type': 'technosphere',
  'production volume': 1,
  'product': 'steel, low-alloyed',
  'name': 'Technology 4',     
  'unit': 'kilogram',            
  'location': 'Region 1'}]

I need this automation to happen for Region 2 by adding conditions, which the suggestion in my code does not work.
for that case would it be any suggestion to try automate creating the values for “exchanges” using the lists as in above and apply the conditions which is related to each Region in a similar approach?

Hi @Shima-Fa

I’m not too sure if I’m fully understanding, but maybe I’m close with this?

Regions     = ['Region 1' , 'Region 2']
Productions = ['Technology 1' , 'Technology 2','Technology 3','Technology 4']

x1 = 1.10
x2 = 1.20
x3 = 1.30
x4 = 1.40

y1 = 2.10
y2 = 2.20
y3 = 2.30
y4 = 2.40

Amounts = {'Region 1': [x1, x2, x3, x4],
           'Region 2': [y1, y2, y3, y4]
           }

Market = []
for r in Regions:
    for i in range(len(Productions)):
            new_exc = [{
                    "uncertainty type": 0,
                    "amount": Amounts.get(r)[i],
                    "type": "technosphere",
                    "production volume": 1,
                    "product": "steel, low-alloyed",
                    "name": Productions[i],
                    "unit": "kilogram",
                    "location": r,
                    }]
            
            Market.extend(new_exc)

I’ll not post the output, because you can run this as is, and assess that for yourself.

@Shima-Fa: You have two different types of data access here. There are lists and there are dictionaries. In a list, you activate elements with number keys,

list1 = ['a', 'b', 'c']
print( list1[1] ) 

# prints: 'b'

Then, you have dictionaries, which are accessed differently, namely through keys like keywords:

dict = {}

dict['car'] = 'Tesla Model S'
dict['plane'] = 'Airbus A380'

print(dict)
# prints {'car': 'Tesla Model S', 'plane': 'Airbus A380'}

So, looping through a list can look like this:

for element in list:
     print (element)

So, looping through a dictionary can look like this:

for key in dict:
     print(key)
     print(dict[key])

I hope this helps!

@RetoSchoelly Thank you very much for the explanation, it was helpful

@rob42 , That is exactly what I was looking for, Thanks again!

1 Like