简体   繁体   中英

Accessing nested key in JSON objects

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 ?

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM