У меня может быть следующая строка JSON:
{ "response" : [ [ { "name" : "LA_",
"uid" : 123456
} ],
[ { "cid" : "1",
"name" : "Something"
} ],
[ { "cid" : 1,
"name" : "Something-else"
} ]
] }
или одно из следующего:
{"error":"some-error"}
{ "response" : [ [ { "name" : "LA_",
"uid" : 123456
} ],
[ { "cid" : "1",
"name" : ""
} ],
[ { "cid" : 1,
"name" : "Something-else"
} ]
] }
{ "response" : [ [ { "name" : "LA_",
"uid" : 123456
} ] ] }
Итак, я не уверен, есть ли все дети и элементы. Будет ли достаточно сделать следующие проверки, чтобы получить Something
значение:
if jsonstr.get('response'):
jsonstr = jsonstr.get('response')[1][0]
if jsonstr:
name = jsonstr.get('name')
if jsonstr: # I don't need empty value
# save in the database
Можно ли это упростить?
Вам не гарантируется, что упорядочение ваших внутренних объектов будет одинаковым при каждом его анализе, поэтому индексирование не является безопасной ставкой для ссылки на индекс объекта с атрибутом name
установленным на Something
.
Вместо того, чтобы вставлять все эти операторы if
, вы можете избавиться от использования понимания списка. Обратите внимание, что если вы повторяете response
ключ, вы получаете список списков, каждый из которых содержит словарь:
>>> data = {"response":[[{"uid":123456,"name":"LA_"}],[{"cid":"1","name":"Something"}],[{"cid":1,"name":"Something-else"}]]}
>>> [lst for lst in data.get('response')]
[[{'name': 'LA_', 'uid': 123456}], [{'name': 'Something', 'cid': '1'}], [{'name': 'Something-else', 'cid': 1}]]
Если вы индексируете первый элемент в каждом списке (lst[0]
), вы получаете список объектов:
>>> [lst[0] for lst in data.get('response')]
[{'name': 'LA_', 'uid': 123456}, {'name': 'Something', 'cid': '1'}, {'name': 'Something-else', 'cid': 1}]
Если вы затем добавите условие if
в ваше понимание списка для соответствия атрибуту name
для объектов, вы получите список с одним элементом, содержащим нужный вам объект:
>>> [lst[0] for lst in data.get('response') if lst[0].get('name') == 'Something']
[{'name': 'Something', 'cid': '1'}]
И затем, индексируя первый элемент этого финального списка, вы получаете желаемый объект:
>>> [lst[0] for lst in data.get('response') if lst[0].get('name') == 'Something'][0]
{'name': 'Something', 'cid': '1'}
Итак, вы можете просто превратить это в функцию и продолжить свою жизнь:
def get_obj_by_name(data, name):
objects = [lst[0] for lst in data.get('response', []) if lst[0].get('name') == name]
if objects:
return objects[0]
return None
print get_obj_by_name(data, 'Something')
# => {'name': 'Something', 'cid': '1'}
print get_obj_by_name(data, 'Something')['name']
# => 'Something'
И он должен быть устойчивым и возвращать None
если ключ response
не найден:
print get_obj_by_name({"error":"some-error"}, 'Something')
# => None