Проверьте, существует ли ключ и повторите попытку массива JSON с помощью Python
У меня есть куча данных JSON из сообщений Facebook, как показано ниже:
{"from": {"id": "8", "name": "Mary Pinter"}, "message": "How ARE you?", "comments": {"count": 0}, "updated_time": "2012-05-01", "created_time": "2012-05-01", "to": {"data": [{"id": "1543", "name": "Honey Pinter"}]}, "type": "status", "id": "id_7"}
Данные JSON являются полуструктурированными, и все это не то же самое.
Ниже мой код:
import json
str = '{"from": {"id": "8", "name": "Mary Pinter"}, "message": "How ARE you?", "comments": {"count": 0}, "updated_time": "2012-05-01", "created_time": "2012-05-01", "to": {"data": [{"id": "1543", "name": "Honey Pinter"}]}, "type": "status", "id": "id_7"}'
data = json.loads(str)
post_id = data['id']
post_type = data['type']
print(post_id)
print(post_type)
created_time = data['created_time']
updated_time = data['updated_time']
print(created_time)
print(updated_time)
if data.get('application'):
app_id = data['application'].get('id', 0)
print(app_id)
else:
print('null')
#if data.get('to'):
#... This is the part I am not sure how to do
# Since it is in the form "to": {"data":[{"id":...}]}
Я хочу, чтобы код печатал to_id как 1543 else print 'null'
Я не уверен, как это сделать.
Спасибо!
Ответы
Ответ 1
import json
jsonData = """{"from": {"id": "8", "name": "Mary Pinter"}, "message": "How ARE you?", "comments": {"count": 0}, "updated_time": "2012-05-01", "created_time": "2012-05-01", "to": {"data": [{"id": "1543", "name": "Honey Pinter"}]}, "type": "status", "id": "id_7"}"""
def getTargetIds(jsonData):
data = json.loads(jsonData)
if 'to' not in data:
raise ValueError("No target in given data")
if 'data' not in data['to']:
raise ValueError("No data for target")
for dest in data['to']['data']:
if 'id' not in dest:
continue
targetId = dest['id']
print("to_id:", targetId)
Вывод:
In [9]: getTargetIds(s)
to_id: 1543
Ответ 2
Если вы хотите только проверить, существует ли ключ или нет
h = {'a': 1}
'b' in h # returns False
Если вы хотите проверить, есть ли значение для ключа
h.get('b') # returns None
Возвращает значение по умолчанию, если отсутствует фактическое значение
h.get('b', 'Default value')
Ответ 3
Рекомендуется создавать вспомогательные служебные методы для подобных вещей, чтобы всякий раз, когда вам нужно было изменить логику проверки атрибута, она находилась в одном месте, и код был бы более читабельным для последователей.
Например, создайте вспомогательный метод (или класс JsonUtils
со статическими методами) в json_utils.py
:
def get_attribute(data, attribute, default_value):
return data.get(attribute) or default_value
а затем использовать его в своем проекте:
from json_utils import get_attribute
def my_cool_iteration_func(data):
data_to = get_attribute(data, 'to', None)
if not data_to:
return
data_to_data = get_attribute(data_to, 'data', [])
for item in data_to_data:
print('The id is: %s' % get_attribute(item, 'id', 'null'))
ВАЖНАЯ ЗАМЕТКА:
Есть причина, по которой я использую data.get(attribute) or default_value
вместо просто data.get(attribute, default_value)
:
{'my_key': None}.get('my_key', 'nothing') # returns None
{'my_key': None}.get('my_key') or 'nothing' # returns 'nothing'
В моих приложениях получение атрибута со значением 'null' - это то же самое, что вообще не получать атрибут. Если ваше использование отличается, вы должны изменить это.
Ответ 4
jsonData = """{"from": {"id": "8", "name": "Mary Pinter"}, "message": "How ARE you?", "comments": {"count": 0}, "updated_time": "2012-05-01", "created_time": "2012-05-01", "to": {"data": [{"id": "1543", "name": "Honey Pinter"}, {"name": "Joe Schmoe"}]}, "type": "status", "id": "id_7"}"""
def getTargetIds(jsonData):
data = json.loads(jsonData)
for dest in data['to']['data']:
print("to_id:", dest.get('id', 'null'))
Попробуйте:
>>> getTargetIds(jsonData)
to_id: 1543
to_id: null
Или, если вы просто хотите пропустить недопустимые идентификаторы вместо печати 'null'
:
def getTargetIds(jsonData):
data = json.loads(jsonData)
for dest in data['to']['data']:
if 'id' in to_id:
print("to_id:", dest['id'])
Итак:
>>> getTargetIds(jsonData)
to_id: 1543
Конечно, в реальной жизни вы, вероятно, не хотите print
каждого идентификатора, но хранить их и что-то делать с ними, но это еще одна проблема.
Ответ 5
if "my_data" in my_json_data:
print json.dumps(my_json_data["my_data"])