Сравнение значения в JSON с использованием Python

1

Я получаю довольно неудобный JSON для работы, который выглядит следующим образом:

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

И я хотел бы сравнить кусочек данных (точнее - значение состояния Button), но я, кажется, терпит неудачу. Пробовал следующее:

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)

К сожалению, я получаю следующее сообщение:

для attrs in (resp ['attributes'] ['value']):

TypeError: индексы индексов должны быть целыми, а не str

  • 1
    Обратите внимание, как ваши значения внутри attributes дополнительно заключены в список; простой доступ к нему с дополнительным [0] должен помочь, т.е. resp['attributes'][0]['value']
  • 0
    Обратите внимание, что то же самое может быть необходимо и для внешнего элемента, так как существует глобальная оболочка списка.
Показать ещё 1 комментарий
Теги:
python-requests
parsing

3 ответа

3
Лучший ответ

В вашем JSON факт, что он завернут в [ then ] означает, что это массив JSON, но только с одним элементом.

Таким образом, как указывает ваше сообщение об ошибке, resp требует целое число в качестве своего индекса, для которого вы хотите, какой элемент массива вам нужен. resp[0] то относится к

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

(теперь обратите внимание на [], поэтому это объект JSON)

Затем вам нужно, чтобы resp[0]['attributes'] ссылался на единственную часть этого объекта, 'attributes' которые снова ссылаются на массив.

Поэтому for attribute in resp[0]['attributes'] позволит вам пройти через этот массив.

Чтобы получить логическое значение, которое вы хотите, вам нужно будет найти, какой элемент этого массива имеет 'name' 'buttonState' и проверить соответствующее 'value'.

В общем, вы, вероятно, ищете что-то вроде:

for attribute in resp[0]['attributes']:
    if attribute['name'] == 'buttonState' and attribute['value']['data'] is False:
        # Do your thing here
  • 0
    Так что изначально это был массив, поэтому для него нужен был индекс. Спасибо!
2

resp - это список, поэтому, чтобы получить первый элемент, resp[0] к нему как resp[0]. То же самое с resp [0] ['attributes']

Таким образом, вы можете получить доступ к нему следующим образом

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

Вы можете перестроить цикл for следующим образом

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

Ответ в сообщении об ошибке я думаю:

TypeError: индексы индексов должны быть целыми, а не str

Первая запись в attributes имеет value которое является списком, поэтому вы не можете получить от него данные. Поскольку у вас есть сочетание типов, вам может потребоваться проверить, является ли "значение" списком или dict.

Редактировать: Я думаю, что подпрыгнул пистолет. @dennlinger дает объяснение вашему сообщению об ошибке. Но вы получите его снова, как только вы пройдете мимо этого...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню