hackerman
hackerman

Reputation: 1291

Parsing JSON dict results in TypeError: list indices must be integers, not str

I have json stored in a dict called rasa_decoded_output which returns the following json:

{
  "entities": [

  ],
  "intent_ranking": [
    {
      "confidence": 0.712699869084774,
      "name": "st_testing"
    },
    {
      "confidence": 0.033084814164303,
      "name": "emergency"
    },
    {
      "confidence": 0.024547592443969,
      "name": "exists_item"
    },
    {
      "confidence": 0.023160524284639,
      "name": "check_out"
    },
    {
      "confidence": 0.022475491594176,
      "name": "broken_climate"
    },
    {
      "confidence": 0.021986762111397,
      "name": "exisits_hours_fitness_center"
    },
    {
      "confidence": 0.019758362302795,
      "name": "st_compliment"
    },
    {
      "confidence": 0.019739803875883,
      "name": "request_profane"
    },
    {
      "confidence": 0.01857200162444,
      "name": "broken_catchall"
    },
    {
      "confidence": 0.016882101663941,
      "name": "exists_vending"
    }
  ],
  "intent": {
    "confidence": 0.072699869084774,
    "name": "st_testing"
  },
  "text": "Testing this stuff"
}

I'm trying to to extract the first occurrence of confidence and name, which I'm doing through the following code:

intent_rank1 = rasa_decoded_output['intent_ranking']['name']
confidence_rank1 = rasa_decoded_output['intent_ranking']['confidence']

However, this is resulting in the error TypeError: list indices must be integers, not str. What is the proper way to store a value from the json into an object. I'm not sure where my misstep is. I suspect it is related to not specifying which occurrence of name or confidence in my code.

My understanding is that in this case there is no issue with it being a dict. Using json.dumps() and looking into it with the same code results in TypeError: string indices must be integers.

Upvotes: 0

Views: 475

Answers (2)

Killswitch
Killswitch

Reputation: 346

The following won't work because rasa_decoded_output['intent_ranking'] is a list (Array equivalent in other languages like Java / C++ / Javascript) of dicts.

intent_rank1 = rasa_decoded_output['intent_ranking']['name']

Solution

  1. If you are sure that confidence and ranking are going to come in the first item in the list then use this -

    intent_rank1 = rasa_decoded_output['intent_ranking'][0]['name']
    confidence_rank1 = rasa_decoded_output['intent_ranking'][0]['confidence']
    
  2. Otherwise, you could use the following

    data = {
        "entities": [...],
        "intent_ranking": [...]
    }    
    
    def get_first_intent_and_confidence(data):
        for info in data.get('intent_ranking', []):
            if 'name' in info and 'confidence' in info:
                return info['name'], info['confidence']
    
    intent, confidence = get_first_intent_and_confidence(data)
    

Upvotes: 0

cs95
cs95

Reputation: 402263

intent_ranking is not a dictionary, but a list of dictionaries. You'll need something along the lines of

intent_rank_i = rasa_decoded_output['intent_ranking'][i]['name']

Or,

confidence_rank_i = rasa_decoded_output['intent_ranking'][i]['confidence']

Where i refers to the ith element in the list.

To iterate over each value, you can use a loop:

for d in rasa_decoded_output['intent_ranking']:
    i = d['name']
    c = d['confidence'] 
    ... # something else

Upvotes: 2

Related Questions