skip to Main Content

I have a JSON received from an API where is A word definition from English Dictionary. I need to parse the data and separate meanings, definitions, and examples but I have some syntax problems with the JSON file.

Here is an example received JSON for the word Handsome:

[{"word":"handsome","phonetic":"/ˈhæn.səm/","phonetics":[{"text":"/ˈhæn.səm/","audio":"https://api.dictionaryapi.dev/media/pronunciations/en/handsome-uk.mp3","sourceUrl":"https://commons.wikimedia.org/w/index.php?curid=9021972","license":{"name":"BY 3.0 US","url":"https://creativecommons.org/licenses/by/3.0/us"}},{"text":"/ˈhæn.səm/","audio":"https://api.dictionaryapi.dev/media/pronunciations/en/handsome-us.mp3","sourceUrl":"https://commons.wikimedia.org/w/index.php?curid=1648256","license":{"name":"BY-SA 3.0","url":"https://creativecommons.org/licenses/by-sa/3.0"}}],"meanings":[{"partOfSpeech":"verb","definitions":[{"definition":"To render handsome.","synonyms":[],"antonyms":[]}],"synonyms":[],"antonyms":[]},{"partOfSpeech":"adjective","definitions":[{"definition":"(of people, things, etc) Having a good appearance; good-looking.","synonyms":[],"antonyms":[],"example":"a handsome garment, house, tree, or horse"},{"definition":"Good, appealing, appropriate.","synonyms":[],"antonyms":[]},{"definition":"Generous or noble in character.","synonyms":[],"antonyms":[],"example":"Handsome is as handsome does."},{"definition":"Ample; moderately large.","synonyms":[],"antonyms":[],"example":"a handsome salary"},{"definition":"(said of things and people) Dexterous; skillful.","synonyms":[],"antonyms":[]}],"synonyms":["hefty","substantial","good-looking","pretty"],"antonyms":[]}],"license":{"name":"CC BY-SA 3.0","url":"https://creativecommons.org/licenses/by-sa/3.0"},"sourceUrls":["https://en.wiktionary.org/wiki/handsome"]}]

I wrote this code to load data and parse the data I want:

data = [{"word":"handsome","phonetic":"/ˈhæn.səm/","phonetics":[{"text":"/ˈhæn.səm/","audio":"https://api.dictionaryapi.dev/media/pronunciations/en/handsome-uk.mp3","sourceUrl":"https://commons.wikimedia.org/w/index.php?curid=9021972","license":{"name":"BY 3.0 US","url":"https://creativecommons.org/licenses/by/3.0/us"}},{"text":"/ˈhæn.səm/","audio":"https://api.dictionaryapi.dev/media/pronunciations/en/handsome-us.mp3","sourceUrl":"https://commons.wikimedia.org/w/index.php?curid=1648256","license":{"name":"BY-SA 3.0","url":"https://creativecommons.org/licenses/by-sa/3.0"}}],"meanings":[{"partOfSpeech":"verb","definitions":[{"definition":"To render handsome.","synonyms":[],"antonyms":[]}],"synonyms":[],"antonyms":[]},{"partOfSpeech":"adjective","definitions":[{"definition":"(of people, things, etc) Having a good appearance; good-looking.","synonyms":[],"antonyms":[],"example":"a handsome garment, house, tree, or horse"},{"definition":"Good, appealing, appropriate.","synonyms":[],"antonyms":[]},{"definition":"Generous or noble in character.","synonyms":[],"antonyms":[],"example":"Handsome is as handsome does."},{"definition":"Ample; moderately large.","synonyms":[],"antonyms":[],"example":"a handsome salary"},{"definition":"(said of things and people) Dexterous; skillful.","synonyms":[],"antonyms":[]}],"synonyms":["hefty","substantial","good-looking","pretty"],"antonyms":[]}],"license":{"name":"CC BY-SA 3.0","url":"https://creativecommons.org/licenses/by-sa/3.0"},"sourceUrls":["https://en.wiktionary.org/wiki/handsome"]}]
json_load = (json.loads(json_data))
print(json_load['meanings'])

this error is shown: list indices must be integers or slices, not str
. If I add [0] to before [meanings] the problem is solved but I don’t know why should I do that: print(json_load[0]['meanings'])

Also, I have the same problem for the inner levels and I cannot parse the data. If I remove the square brackets from the beginning and end of the JSON string, there is no more need for [0] before [meanings].

What should I do? Do I need to add numbers before keys or do I have to remove square brackets for all levels?

4

Answers


  1. Your API response is wrapped in a list, presumably because it could have returned multiple results.

    So yeah, you would "add numbers before keys" (i.e. access the zeroth member of the array); I’d just guard against unexpectedly getting multiple results, and then grab the zeroth one and work on that.

    parsed_data = json.loads(json_data)
    if len(parsed_data) != 1:
        raise ValueError(f"Oops, got {len(parsed_data)} results!")
    first_definition = parsed_data[0]
    
    print(first_definition["word"], "(", first_definition["phonetic"], ")")
    
    for meaning in first_definition["meanings"]:
        print("*", meaning["partOfSpeech"])
        for defn in meaning["definitions"]:
            print("  *", defn["definition"])
        # ... etc...
    
    Login or Signup to reply.
  2. { and [ are separate brackets. The first means "here follows an ‘object’" whereas the second means "here follows a list". Therefore, if you paste the raw data that you got from the API

    [
      {
        "word":"handsome",
        "phonetic":"/ˈhæn.səm/",
        "phonetics": [
          {
            "text":"/ˈhæn.səm/",
          
      "audio":"https://api.dictionaryapi.dev/media/pronunciations/en/handsome-uk.mp3",
            "sourceUrl":"https://commons.wikimedia.org/w/index.php?curid=9021972","license":{"name":"BY 3.0 US",
    ...
    

    You have a list, containing an object (or potentially multiple). So the best thing to do is indeed use the numerical index 0 to get the first object in the list. Or even better, first check how many objects are in the list with len(json_load).

    Login or Signup to reply.
  3. the error you get means that you are trying to access a list item using a string key (wich is impossible, you can access lists using int index only).

    • you need to access the list first then you can access the inner json key value pairs

    • same for any inner lists inside the json you need to specify the index first then you can access the data

    Login or Signup to reply.
  4. If you’re getting those data from some API then it’s likely that you’re getting them as a string. So let’s make your data into a string like this:

    js = '''[{"word":"handsome","phonetic":"/ˈhæn.səm/","phonetics":[{"text":"/ˈhæn.səm/","audio":"https://api.dictionaryapi.dev/media/pronunciations/en/handsome-uk.mp3","sourceUrl":"https://commons.wikimedia.org/w/index.php?curid=9021972","license":{"name":"BY 3.0 US","url":"https://creativecommons.org/licenses/by/3.0/us"}},{"text":"/ˈhæn.səm/","audio":"https://api.dictionaryapi.dev/media/pronunciations/en/handsome-us.mp3","sourceUrl":"https://commons.wikimedia.org/w/index.php?curid=1648256","license":{"name":"BY-SA 3.0","url":"https://creativecommons.org/licenses/by-sa/3.0"}}],"meanings":[{"partOfSpeech":"verb","definitions":[{"definition":"To render handsome.","synonyms":[],"antonyms":[]}],"synonyms":[],"antonyms":[]},{"partOfSpeech":"adjective","definitions":[{"definition":"(of people, things, etc) Having a good appearance; good-looking.","synonyms":[],"antonyms":[],"example":"a handsome garment, house, tree, or horse"},{"definition":"Good, appealing, appropriate.","synonyms":[],"antonyms":[]},{"definition":"Generous or noble in character.","synonyms":[],"antonyms":[],"example":"Handsome is as handsome does."},{"definition":"Ample; moderately large.","synonyms":[],"antonyms":[],"example":"a handsome salary"},{"definition":"(said of things and people) Dexterous; skillful.","synonyms":[],"antonyms":[]}],"synonyms":["hefty","substantial","good-looking","pretty"],"antonyms":[]}],"license":{"name":"CC BY-SA 3.0","url":"https://creativecommons.org/licenses/by-sa/3.0"},"sourceUrls":["https://en.wiktionary.org/wiki/handsome"]}]'''
    

    Now…

    import json
    
    jlist = json.loads(js)
    
    print(jlist[0]["meanings"])
    

    However, if you’ve already processed the API response and have the data as shown in the question then it’s just:

    js = [{"word":"handsome","phonetic":"/ˈhæn.səm/","phonetics":[{"text":"/ˈhæn.səm/","audio":"https://api.dictionaryapi.dev/media/pronunciations/en/handsome-uk.mp3","sourceUrl":"https://commons.wikimedia.org/w/index.php?curid=9021972","license":{"name":"BY 3.0 US","url":"https://creativecommons.org/licenses/by/3.0/us"}},{"text":"/ˈhæn.səm/","audio":"https://api.dictionaryapi.dev/media/pronunciations/en/handsome-us.mp3","sourceUrl":"https://commons.wikimedia.org/w/index.php?curid=1648256","license":{"name":"BY-SA 3.0","url":"https://creativecommons.org/licenses/by-sa/3.0"}}],"meanings":[{"partOfSpeech":"verb","definitions":[{"definition":"To render handsome.","synonyms":[],"antonyms":[]}],"synonyms":[],"antonyms":[]},{"partOfSpeech":"adjective","definitions":[{"definition":"(of people, things, etc) Having a good appearance; good-looking.","synonyms":[],"antonyms":[],"example":"a handsome garment, house, tree, or horse"},{"definition":"Good, appealing, appropriate.","synonyms":[],"antonyms":[]},{"definition":"Generous or noble in character.","synonyms":[],"antonyms":[],"example":"Handsome is as handsome does."},{"definition":"Ample; moderately large.","synonyms":[],"antonyms":[],"example":"a handsome salary"},{"definition":"(said of things and people) Dexterous; skillful.","synonyms":[],"antonyms":[]}],"synonyms":["hefty","substantial","good-looking","pretty"],"antonyms":[]}],"license":{"name":"CC BY-SA 3.0","url":"https://creativecommons.org/licenses/by-sa/3.0"},"sourceUrls":["https://en.wiktionary.org/wiki/handsome"]}]
    
    print(js[0]["meanings"])
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search