user636322
user636322

Reputation: 1201

Python for loop json.loads error string indices must be integers

I'm have been struggling with understanding the reason for the following Json parsing issue, I have tried many combinations to access the 'val' item value but I have hit a brick wall.

I have used the code below successfully on 'similar' Json style data, but I dont have the knowledge to craft this approach to the data below.

All advice gratefully accepted.

result = xmltodict.parse(my_read)
result = result['REPORT']['REPORT_BODY']
result =json.dumps(result, indent=1)

    print(result)

    {
 "PAGE": [
     {
      "D-ROW": [
       {
        "@num": "1",
        "type": "wew",
        "val": ".000"
       },
       {
        "@num": "2",
        "type": "wew",
        "val": ".000"
       }
      ]
     },
     {
      "D-ROW": [
       {
        "@num": "26",
        "type": "wew",
        "val": ".000"
       },
       {
        "@num": "27",
        "type": "wew",
        "val": ".000"
       },
       {
        "@num": "28",
        "type": "wew",
        "val": ".000"
    }
   ]
  }
 ]
}

for item in json.loads(json_data):
    print(item['PAGE']['D-ROW']['val']

error string indices must be integers

Upvotes: 1

Views: 2149

Answers (4)

bakkal
bakkal

Reputation: 55448

The first thing should notice, based on your JSON structure is that it's a dict {"PAGE": [...], ...}, so when you use json.loads() on it, you'll get a dict too

In this for loop, your item iterator actually refers to the key from the dict

for item in json.loads(json_data):
    print(item['PAGE']['D-ROW']['val']

Here's a simpler example easier to follow

>>> for key in json.loads('{"a": "a-value", "b": "b-value"}'):
...     print(key)
...
a
b

error string indices must be integers

So you can guess that in your loop item would refer to the key "PAGE", and you can't index that string with ['D-ROW'] ("PAGE"['D-ROW'] doesn't make sense, hence your error)

Key/values in the for loop

To get items if you use the loop below, item becomes a tuple of (key, value)

for item in json.loads(json_data).items():
        print(item)

You can also expand the key, value like this

>>> for key, value in json.loads('{"a": "a-value", "b": "b-value"}').items():
...     print("key is {} value is {}".format(key, value))
...
key is a value is a-value
key is b value is b-value

Upvotes: 2

warvariuc
warvariuc

Reputation: 59604

"D-ROW": [
       {
        "@num": "26",
        "type": "wew",
        "val": ".000"
       },
       {
        "@num": "27",
        "type": "wew",
        "val": ".000"
       },
       {
        "@num": "28",
        "type": "wew",
        "val": ".000"
    }

D-ROW key contains a list, not a dict.

You should change

print(item['PAGE']['D-ROW']['val']

to

print([_item['val'] for _item in item['PAGE']['D-ROW']])

to iterate over the list which contains you dicts.

Upvotes: 1

Tom O' Mara
Tom O' Mara

Reputation: 267

Your JSON should not include quotes around values with numbers. For example, change

"D-ROW": [
   {
    "@num": "1",
    "type": "wew",
    "val": ".000"
   },

to

"D-ROW": [
   {
    "@num": 1, // Key requires quotes, Value omits quotes if number
    "type": "wew",
    "val": 0.000
   },

Upvotes: 1

enrico.bacis
enrico.bacis

Reputation: 31504

item['PAGE'] contains a list, so you cannot index it with 'D-ROW'. If your json-loaded data is in a variable data you could use:

for page in data['PAGE']:
    for drow in page['D-ROW']:
        print drow['val']

Upvotes: 2

Related Questions