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.

6
  • Possible duplicate of Converting JSON String to Dictionary Not List Commented Jan 22, 2019 at 22:48
  • @Primusa No I don't think so. Commented Jan 22, 2019 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: stackoverflow.com/questions/4326658/… Commented Jan 22, 2019 at 22:51
  • 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] Commented Jan 22, 2019 at 22:54
  • 1
    print(list(my_data["9"][0].values())[0]) Commented Jan 22, 2019 at 22:56

4 Answers 4

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'
Sign up to request clarification or add additional context in comments.

Comments

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', ... }

Comments

1

Thanks to @Primusa for the comment.

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

2 Comments

@davedwards It says I can't answer my own question for 2 days.
@davedwards Someone else commented the same thing after me anyway, so I just accepted that one.
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}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.