skip to Main Content

This is what my JSON file looks like:

[
    {
        "id": 13445,
        "uuid": "bf1923c5-a198-409b-851e-c67f7b8a661e",
        "created_at": "2021-07-27 12:41:31.715922",
        "updated_at": "2021-11-10 21:41:41.857982",
        "meta": {
            "osm_id": null,
            "google_maps_place_id": "ChIJO4sAE5d-1EARsPwZh_s6eX4"
        },
        "type": "VILLAGE",
        "name": {
            "en": "Dіbrіvka",
            "ru": "Дибривка",
            "uk": "Дібрівка"
        },
        "public_name": {
            "en": "village Dіbrіvka",
            "ru": "п. Дибривка",
            "uk": "с. Дібрівка"
        },
        "post_code": [
            "09226"
        ],
        "katottg": "UA32120130090047792",
        "koatuu": "3222281602",
        "lng": 30.9903521,
        "lat": 49.88724620000001,
        "parent_id": 1051
    }
]

With the following code I can read JSON and convert it to a Python dict

with open('ua_locations.json', 'r',  encoding="utf-8") as user_file:
    file_contents = user_file.read()
    json_object = json.loads(file_contents)[0]

print(type(json_object))
print(json_object['id']['public_name']['lng']['lat'])

How can I include only 4 fields: id, public name, lng, lat for each element in the list?

2

Answers


  1. You are chaining the keys in your example, it isn’t what you expected.

    You aren’t getting the keys of the same object in order, your example will only work if the object is a nested dictionary with the following structure:

    d = {'id': {'public_name': {'lng': {'lat': 42}}}}
    

    In JSON format:

    {
        "id": {
            "public_name": {
                "lng": {
                    "lat": 42
                }
            }
        }
    }
    

    d['id']['public_name']['lng']['lat'] means walk from left to right, get the value associated with the current key from the current object, and assign the value to current object. The result is 42.

    You want the fields, you need to query the same object for the fields like so:

    (d['id'], d['public_name'], d['lng'], d['lat'])
    

    This gets the field values but omits the field names.

    To get the field name and values, use either of the following comprehensions:

    {k: v for k, v in d.items() if k in {'id', 'public_name', 'lng', 'lat'}}
    

    Or

    {k: d[k] for k in ['id', 'public_name', 'lng', 'lat']}
    

    The first preserves the order of the keys as they appear in the dict, the second guarantees all the items have the same order of fields, but the second can only work if all fields are present.

    Your top level data is a list, it doesn’t support using strings are indexes, if you want to apply the above operations to one element, use indexing to get the element and apply the operations like so:

    d = json_object[0]
    print({k: d[k] for k in ['id', 'public_name', 'lng', 'lat']})
    

    Use 0 for the first object, 1 for the second, et cetera.

    You can define a function to reuse the same code:

    def filter_fields(d):
        return {k: d[k] for k in ['id', 'public_name', 'lng', 'lat']}
    

    Finally to apply the transformations to all elements of the list, use a list comprehension:

    import json
    
    with open('ua_locations.json', 'r',  encoding='utf8') as f:
        file = f.read()
    
    data = json.loads(file)
    
    [{k: e[k] for k in ['id', 'public_name', 'lng', 'lat']} for e in data]
    
    Login or Signup to reply.
  2. Create a list (or tuple) of the keys you’re interested in. You can then combine a dictionary comprehension within a list comprehension as follows:

    import json
    
    INPUT_FILE = '/Volumes/G-Drive/ua_locations.json'
    KEYS = ('id', 'public_name', 'lng', 'lat')
    
    with open(INPUT_FILE) as j:
        for d in [{k: item.get(k) for k in KEYS} for item in json.load(j)]:
            print(d)
    

    Output:

    {'id': 13445, 'public_name': {'en': 'village Dіbrіvka', 'ru': 'п. Дибривка', 'uk': 'с. Дібрівка'}, 'lng': 30.9903521, 'lat': 49.88724620000001}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search