1

I receive a fairly uncomfortable JSON to work with, which looks as follows:

[
{
    "attributes": [
        {
            "type": "COMMAND",
            "name": "COMMAND",
            "value": [
                "buttonState"
            ]
        },
        {
            "type": "std_msgs.msg.Bool",
            "name": "buttonState",
            "value": {
                "data": false
            }
        }
    ],
    "type": "sensor",
    "id": "s_2"
}]

And I would like to compare a piece of data (more precisely - value of Button state) but I seem to fail. Tried following:

import requests
import json
yo = 1
switchPost = "http://192.168.0.104:7896/iot/d?k=123456789&i=san_1_switch&d=sw|{}"
robGet = "http://192.168.0.109:10100/robot/sen_2"

r = requests.get(robGet, headers={"content-type":"application/json"})
resp = json.loads(r.text)

for attrs in (resp['attributes']['value']):
    if attrs['data'] == false:
        yo = 100
        break
    
g = requests.post(switchPost.format(yo), headers={"content-type":"text/plain"})
print(r.text)

Unfortunately, the error I receive is the following:

for attrs in (resp['attributes']['value']):

TypeError: list indices must be integers, not str

3
  • 1
    Note how your values inside of attributes are additionally wrapped in a list; simply accessing it with an additional [0] should do the trick, i.e. resp['attributes'][0]['value'] Commented Jul 9, 2018 at 14:58
  • Note that the same might be necessary for the outer element as well, since there is a global list wrapper as well. Commented Jul 9, 2018 at 14:59
  • @dennlinger Thanks, I will take the following into consideration next time! Commented Jul 11, 2018 at 13:01

3 Answers 3

3

In your JSON, the fact that it is wrapped in [ then ] means it is a JSON array, but with just one element.

So, as your error message suggests, resp needs an integer as its index, for which element of the array you want. resp[0] then refers to

{
    "attributes": [
        {
            "type": "COMMAND",
            "name": "COMMAND",
            "value": [
                "buttonState"
            ]
        },
        {
            "type": "std_msgs.msg.Bool",
            "name": "buttonState",
            "value": {
                "data": false
            }
        }
    ],
    "type": "sensor",
    "id": "s_2"
}

(notice no [] now, so it's a JSON object)

Then you want resp[0]['attributes'] to refer to the single part of this object, 'attributes' which again refers to an array.

Therefore for attribute in resp[0]['attributes'] will allow you to loop through this array.

To get the boolean value you want, you'll then want to find which element of that array has 'name' of 'buttonState' and check the corresponding 'value'.

In all, you're probably looking for something like:

for attribute in resp[0]['attributes']:
    if attribute['name'] == 'buttonState' and attribute['value']['data'] is False:
        # Do your thing here
Sign up to request clarification or add additional context in comments.

1 Comment

So it was an array initially, that's why it needed an index to refer to. Thanks!
2

resp is a list so, to get first element, access it as resp[0]. Same with resp[0]['attributes']

So you can access it as follows

resp[0]['attributes'][0]['value']

You can restructure your for loop as follows

for d in resp[0]['attributes']:
    if isinstance(d['value'], dict) and d['value'].get('data') == false:
        yo = 100
        break

Comments

1

The answer is in the error message I think:

TypeError: list indices must be integers, not str

The first entry in attributes has a value that is a list, so you can't get 'data' from that. Since you have a mix of types, you might need to check if 'value' is a list or a dict.

Edit: Jumped the gun here I think. @dennlinger gives an explanation to your error message. But you'll get it again once you're past that...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.