Home > Back-end >  Can't read json file after second {}
Can't read json file after second {}

Time:06-30

I have JSON data that I need to read and then print:

"city": {
     "coord": {
         "lat": 52.2183,
         "lon": 6.8958
     },
     "country": "NL",
     "id": 2756071,
     "name": "Enschede",
     "population": 153655,
     "sunrise": 1656472443,
     "sunset": 1656532643,
     "timezone": 7200
 },
 "cnt": 40,
 "cod": "200",
 "list": [
     {
         "clouds": {
             "all": 50
         },
         "dt": 1656536400,
         "dt_txt": "2022-06-29 21:00:00",
         "main": {
             "feels_like": 295.23,
             "grnd_level": 1007,
             "humidity": 60,
             "pressure": 1012,
             "sea_level": 1012,
             "temp": 295.38,
             "temp_kf": 2.77,
             "temp_max": 295.38,
             "temp_min": 292.61
         },
         "pop": 0,
         "sys": {
             "pod": "n"
         },
         "visibility": 10000,
         "weather": [
             {
                 "description": "scattered clouds",
                 "icon": "03n",
                 "id": 802,
                 "main": "Clouds"
             }
         ],
         "wind": {
             "deg": 99,
             "gust": 1.93,
             "speed": 1.9
         }
     }

Now I want to read: feels_like, temp, etc. I can read the first part on top with:

print(json_load['city']['coord'])

But if I want to read:

print(json_load['list']['main'])

I get a keyword error 0.

CodePudding user response:

Since json_load['list'] is a list, you have to use indices to access the items in it. Here's how to get the contents of the first (zeroth) element of it:

print(json_load['list'][0]['main']['feels_like'])  # -> 295.23
print(json_load['list'][0]['main']['temp'])  # -> 295.38

CodePudding user response:

I would personally use something like dotwiz for fast, easy attribute-style access with dict and nested dict objects. This library is available on pip:

pip install dotwiz

Usage:

from dotwiz import DotWiz

json_load = {
    "city": {
        "coord": {
            "lat": 52.2183,
            "lon": 6.8958
        },
    },
    "list": [
        {
            "main": {
                "feels_like": 295.23,
                "temp": 295.38,
            },
        }
    ]}


dw = DotWiz(json_load)

print(dw)
print(dw.city.coord)
print()

assert dw.city.coord.lon == 6.8958

print('temp:', dw.list[0].main.temp)
print('feels like:', dw.list[0].main.feels_like)

Prints:

✫(city=✫(coord=✫(lat=52.2183, lon=6.8958)), list=[✫(main=✫(feels_like=295.23, temp=295.38))])
✫(lat=52.2183, lon=6.8958)

temp: 295.38
feels like: 295.23

If you need field auto completion and type hinting support for use in an IDE, I would suggest to subclass from DotWiz, and then define only the fields you want to access:

from __future__ import annotations

from dotwiz import DotWiz


class MyDotClass(DotWiz):
    city: City
    list: list[ListData]

class City:
    coord: Coord

class Coord:
    lat: float
    lon: float

class ListData:
    main: Main

class Main:
    feels_like: float
    temp: float


dw = MyDotClass(json_load)
# rest same as above...

Disclaimer: I am the creator and maintener of this library.

  • Related