0

I'm trying to retrieve the area value and the first pair of coordinates value for every area from a JSON list of dictionaries after an API call

[{'area': 'abcd', 'geojson': '{"type":"MultiPolygon","coordinates":[[[[103.8593,1.43905,...[103.6391,1.3527]]]]}'},
 {'area': 'efgh', 'geojson': '{"type":"MultiPolygon","coordinates":[[[[100.000,1.4000,...[103.6391,1.3527]]]]}'}
.
.

This is my code

# calling the API 
results = requests.get(url).json()

area= []
coordinates = []

for i in results:
    a = i['pln_area_n'] 
    area.append(a)

for x in results:
    c = x['geojson']['coordinates'][0]
    coordinates.append(c)
TypeError: string indices must be integers

My code is definitely wrong, how do I access the first pair of coordinates value of the geojson key for every area?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
est
  • 51
  • 5
  • 1
    `x['geojson']` is a **string**, you need to `json.load` it into a dictionary to be able to access the `'coordinates'`. The format of the API you're hitting seems a bit weird, I might be inclined to look at fixing this upstream. – jonrsharpe Nov 23 '19 at 11:21
  • 1
    @jonrsharpe You should post an answer showing how to deal with it. It seems like it's intentional, they did call that property `geojson`, indicating that it contains JSON, not an object. – Barmar Nov 23 '19 at 11:25
  • @jonrsharpe it is weird, am looking into the api call. json.load and .json() works the same too as discussed in this thread? https://stackoverflow.com/questions/39719689/what-is-the-difference-between-json-load-and-json-loads-functions – est Nov 23 '19 at 12:01
  • What do you mean *"works the same too"*? The point is that you need to parse parts of it *twice*; once to get what you show in your question, then again for the content of the `geojson` values. As @Barmar has pointed out, the name suggests that a JSON string is expected for that value. – jonrsharpe Nov 23 '19 at 12:04

1 Answers1

-1

I'd guess your response is something like:

[{"area": "abcd", "geojson": "{\"type\": \"MultiPolygon\", ...}"}]

The values of the geojson property in the JSON are themselves JSON strings, and requests will only parse the first "level" of this. Hence you end up with the Python list:

[{'area': "abcd', 'geojson': '{"type": "MultiPolygon", ...}'}]

where the results[0]['geojson'] value is still a JSON object string, not parsed to a dictionary. This explains the error; '{"type": "MultiPolygon", ...}'['coordinates'] is trying to index into a string using another string, not accessing a dictionary's value by key:

>>> '{"type": "MultiPolygon", ...}'['coordinates']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: string indices must be integers

You therefore need to import json and parse the JSON string values again, e.g. using a list comprehension:

coordinates = [
    json.loads(result['geojson'])['coordinates'][0]
    for result in results
]
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437