0

I want to access a specific key value ("cote_1989_base") in Python to modify it. But I have a TypeError: string indices must be integers.

My code:

import json

with open('demo_db_algolia_2019.json', encoding='utf-8') as data_file:
    data = json.loads(data_file.read())
    for x in data:
        cote1989base = x.get(["cote"][0]["cote_1989"]["cote_1989_eu"]["cote_1989_base"])
        print(cote1989base)

EDIT: Maybe I didn't explain this well because my entire JSON is in an array like this:

    [{
    "objectID": 10035,
    "cote":
    {
        "cote_1989":
        {
            "cote_1989_f": "750000F",
            "cote_1989_eu":
            {                    
                "cote_1989_base": 190140                    
            }
        },
        "cote_2004":
        {                
            "cote_2004_base": 173320                
        },
        "cote_2014":
        {                
            "cote_2014_base": 420800                
        },
        "cote_2017":
        {                
            "cote_2017_base": 939600                
        },
        "cote_2019":
        {                
            "cote_2019_base": 939600                
        }
    }
},
    {
    "objectID": 10202,
    "cote":
    {
        "cote_1989":
        {
            "cote_1989_f": "27000F",
            "cote_1989_eu":
            {                    
                "cote_1989_base": 6844                    
            }
        },
        "cote_2004":
        {
            "cote_2004_base": 10894                
        },
        "cote_2014":
        {
            "cote_2014_base": 23670
        },
        "cote_2017":
        {                
            "cote_2017_base": 46980
        },
        "cote_2019":
        {                
            "cote_2019_base": 51156
        }
    }
}
]

Does it change something to the main problem ?

4
  • What you have is not a valid json, also do type(data) to check the type of data Commented Jun 20, 2019 at 8:00
  • I edited the JSON. It's just a sample of my database but it is valid when I test it. Commented Jun 20, 2019 at 8:21
  • That code should raise AttributeError: 'str' object has no attribute 'get' and that is exactly what it does here. Commented Jun 20, 2019 at 8:38
  • Well, ["cote"][0] is a string so ["cote"][0]["cote_1989"] just does not make sense. What else do you expect? Commented Jun 20, 2019 at 20:26

3 Answers 3

2

you should access keys as following :

x.get("cote").get("cote_1989").get("cote_1989_eu").get("cote_1989_base")

or you can use the following function to simplify the code:

def find(data, key):
    parts = key.split('/')
    dd = data
    for part in parts:
         if ( dd == None or not isinstance(dd,dict)):
            return None
         dd = dd.get(part)         
    return dd    

>>> data = { 'a' : { 'b' : { 'c' : { 'd':5} , 'c1':8 } }}
>>> find(data, 'a/b/c/d'))
5
>>> find(data, 'a/b/c2')
8
>>> find(data, 'z/b')
None
Sign up to request clarification or add additional context in comments.

2 Comments

I have an AttributeError: 'NoneType' object has not attribute 'get', maybe because sometimes, "cote_1989" keys have no value
probably. You can use the above function to simplify the code.
0

This bit: x.get(["cote"][0]["cote_1989"] is certainly wrong. Here the square brackets are not a dict lookup, it is a list literal, so ["cote"][0] evaluates to "cote".

Then you proceed to subscript that with ["cote_1989"] which is where your TypeError comes from.

You should chain .get() calls:

x.get("cote").get("cote_1989").get("cote_1989_eu").get("cote_1989_base")

That treats the [0] bit is 'line noise' in your original code, assuming your original JSON is correct.

Comments

0

There is an error in the JSON. There is a mismatch of braces. Use this.

import json


j = '''
{
    "objectID": 10035,
    "cote": {
        "cote_1989": {
            "cote_1989_f": "750000F",
            "cote_1989_eu": {
                "cote_1989_excp": 266196,
                "cote_1989_concours": 228168,
                "cote_1989_base": 190140,
                "cote_1989_be": 152112,
                "cote_1989_me": 114084,
                "cote_1989_ar": 76056,
                "cote_1989_epa": 38028
            }
        },
        "cote_2004": {
            "cote_2004_excp": 242648,
            "cote_2004_concours": 207984,
            "cote_2004_base": 173320,
            "cote_2004_be": 138656,
            "cote_2004_me": 103992,
            "cote_2004_ar": 69328,
            "cote_2004_epa": 34664
        }
    }
}'''

data = json.loads(j)
print(data['cote']['cote_1989']['cote_1989_eu']['cote_1989_base'])

Output:

190140

1 Comment

Change the line data = json.loads(j) to data = json.loads(data_file.read()) and make sure the JSON doesn't have errors. If possible, use vscode to check the json file. Open the .json file using vscode, it'll show if the file has errors.

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.