2

I would like to take some JSON, convert it into a dictionary and then change some of the values in that dictionary.

I've tried a few things as shown below but I can't get it to work as intended.

My JSON is as follows:

{
   "9":[
      {
         "09_000":{
            "name":"Wyatt Feldt",
            "1":"R",
            "2":"L",
            "w":1,
            "h_t":1
         }
      },
      {
         "09_001":{
            "name":"Clayton Friend",
            "1":"R",
            "2":"R",
            "w":0,
            "h_t":0
         }
      }
   ],
   "10":[
      {
         "09_000":{
            "name":"Wyatt Feldt",
            "1":"R",
            "2":"L",
            "w":1,
            "h_t":1
         }
      },
      {
         "09_001":{
            "name":"Clayton Friend",
            "1":"R",
            "2":"R",
            "w":0,
            "h_t":0
         }
      }
   ],
   "11":[
      {
         "09_000":{
            "name":"Wyatt Feldt",
            "1":"R",
            "2":"L",
            "w":1,
            "h_t":1
         }
      },
      {
         "09_001":{
            "name":"Clayton Friend",
            "1":"R",
            "2":"R",
            "w":0,
            "h_t":0
         }
      }
   ]
}

And then in Python I have written print(my_data["9"][0]) which returns {'09_000': {'name': 'Wyatt Feldt', '1': 'R', '2': 'L', 'w': 1, 'h_t': 1}}.

However, I just want it to return {'name': 'Wyatt Feldt', '1': 'R', '2': 'L', 'w': 1, 'h_t': 1} because I don't just want to print it, I want to set some of the values e.g. the name. And I know I can do that by doing my_data["9"][0]["09_000"] but I don't want to use that ID in order to get it (only the outer group, the index and then the key e.g. "name"). Since I'm already returning {'09_000': {'name': 'Wyatt Feldt', '1': 'R', '2': 'L', 'w': 1, 'h_t': 1}} I'm sure there must be a way to just get the nested part ({'name': 'Wyatt Feldt', '1': 'R', '2': 'L', 'w': 1, 'h_t': 1}) so I can change the values.

EDIT: I think it's a different issue. My my_data variable is already in dictionary format, and this is a special case of indexing.

J P
  • 541
  • 1
  • 10
  • 20
  • Possible duplicate of [Converting JSON String to Dictionary Not List](https://stackoverflow.com/questions/19483351/converting-json-string-to-dictionary-not-list) – Primusa Jan 22 '19 at 22:48
  • @Primusa No I don't think so. – J P Jan 22 '19 at 22:49
  • There's two parts to this question. The first part of the question is how to convert a json string to a dict. The second part is how to index a dictionary: https://stackoverflow.com/questions/4326658/how-to-index-into-a-dictionary – Primusa Jan 22 '19 at 22:51
  • @Primusa I edited to clarify that I have already achieved the first part. And the second part is different to the one you have linked. – J P Jan 22 '19 at 22:52
  • 1
    To get a specific value from a dictionary you generally have to index it. If there's just one value you can do something like `val = list(dict.values())[0]` – Primusa Jan 22 '19 at 22:54
  • 1
    `print(list(my_data["9"][0].values())[0])` – CristiFati Jan 22 '19 at 22:56

4 Answers4

2

If you have your JSON text in a string, say its name is my_json, then you can use Python's json.loads to convert it to a dictionary.

import json
register = json.loads(my_json)

In side your dictionary, you have keys "9", "10", "11". For each of those, you have a list of two items you can iterate through. And each of the items in the list is a dictionary of one key. You could just iterate through these last keys without knowing what they are:

for k in register:
    for block in register[k]:
        for block_key in block:
            print(block[block_key])

The output I get from this is:

{u'1': u'R', u'h_t': 1, u'2': u'L', u'name': u'Wyatt Feldt', u'w': 1}
{u'1': u'R', u'h_t': 0, u'2': u'R', u'name': u'Clayton Friend', u'w': 0}
{u'1': u'R', u'h_t': 1, u'2': u'L', u'name': u'Wyatt Feldt', u'w': 1}
{u'1': u'R', u'h_t': 0, u'2': u'R', u'name': u'Clayton Friend', u'w': 0}
{u'1': u'R', u'h_t': 1, u'2': u'L', u'name': u'Wyatt Feldt', u'w': 1}
{u'1': u'R', u'h_t': 0, u'2': u'R', u'name': u'Clayton Friend', u'w': 0}

If you know that your lists are always going to contain items of one key, then another way to do it is use block.keys() to generate the list of dictionary keys, then take the first (and only) item in the list:

for k in register:
    for block in register[k]:
        print(block[block.keys()[0]])

In any case, you can replace the print statement I've used with some command to change whatever you need. Though to make it easier to get to the right location, try using the index numbers of the list:

for k in register:
    for i in range(len(register[k])):
        for key in register[k][i]:
            original_name = register[k][i][key][u'name']
            if original_name == u'Wyatt Feldt':
                register[k][i][key][u'name'] = 'Wyatt Erp'
Bill M.
  • 1,388
  • 1
  • 8
  • 16
1

Thanks to @Primusa for the comment.

I have done print(list(my_data["9"][0].values())[0]) and it works as intended.

J P
  • 541
  • 1
  • 10
  • 20
1

In general, if you know there's only one key-value pair in the inner dictionary and you just want its value, you can enumerate the values and then access the first one, like so:

wyatt = list(my_data["9"][0].values())[0] # {'name': 'Wyatt Feldt', ... }
ethan.roday
  • 2,485
  • 1
  • 23
  • 27
0

If you want to access that particular element, then you can do something like the following:

n_entry = 0
entry_key_name = f'09_{n_entry:03}'  # If using >= python 3.6
# entry_key_name = '09_{:03}'.format(n_entry)  # If using < python 3.6
print(register["9"][n_entry][entry_key_name])

Result:

{'name': 'Wyatt Feldt', '1': 'R', '2': 'L', 'w': 1, 'h_t': 1}
PMende
  • 5,171
  • 2
  • 19
  • 26