#python #json #python-3.x #dictionary
Вопрос:
Хотите получить данные MetaEntry из словаря, но каждый раз ключи отличаются некоторыми случайными именами.
например: ['Client']
dictionary = {
"Tags":[],
"ObjectId":
"ab9c6448-85fe-eb11-b563-281878c3a7fe",
"Client": {
"MetaData": {
"MetaEntry": [
{
"Key": "status",
"Value": "Active"
},
{
"Key": "first_day_of_week",
"Value": "Monday"
},
{
"Key": "default_induction_expiry",
"Value": "0"
}
]
},
"RelatedLinks": [],
"Tags": [],
"ObjectId": "6cf54386-d81a-eb11-9fb4-281878b13795",
"Type": "Artifice.Web.Data.Entities.Client",
"Name": "Amco Logictics "
}
}
печать(словарь[‘Клиент’][‘Метаданные’][‘MetaEntry’])
здесь ['Client']
ключ будет меняться случайным образом, поэтому моя вышеприведенная забава с печатью не сработает, есть ли обходной способ получить ключ ['MetaData']['MetaEntry']
без жесткого кодирования ['Client']
?
Комментарии:
1. посмотрите на путь json — pypi.org/project/jsonpath-ng
Ответ №1:
Если у вас глубоко вложенный словарь, вы можете рекурсивно просмотреть его, чтобы найти все MetaEntry
ключи:
dictionary = {
"Tags": [],
"ObjectId": "ab9c6448-85fe-eb11-b563-281878c3a7fe",
"Client": {
"MetaData": {
"MetaEntry": [
{"Key": "status", "Value": "Active"},
{"Key": "first_day_of_week", "Value": "Monday"},
{"Key": "default_induction_expiry", "Value": "0"},
]
},
"RelatedLinks": [],
"Tags": [],
"ObjectId": "6cf54386-d81a-eb11-9fb4-281878b13795",
"Type": "Artifice.Web.Data.Entities.Client",
"Name": "Amco Logictics ",
},
}
def find(d):
if isinstance(d, dict):
if "MetaEntry" in d:
yield d["MetaEntry"]
else:
for k, v in d.items():
yield from find(v)
elif isinstance(d, list):
for v in d:
yield from find(v)
for meta_entry in find(dictionary):
print(meta_entry)
С принтами:
[
{"Key": "status", "Value": "Active"},
{"Key": "first_day_of_week", "Value": "Monday"},
{"Key": "default_induction_expiry", "Value": "0"},
]
ИЗМЕНИТЬ: Для печати текущего пути:
def find(d, cur_path=None):
if cur_path is None:
cur_path = []
if isinstance(d, dict):
if "MetaEntry" in d:
yield d["MetaEntry"], cur_path ["MetaEntry"]
else:
for k, v in d.items():
yield from find(v, cur_path [k])
elif isinstance(d, list):
for i, v in enumerate(d):
yield from find(v, cur_path [i])
for meta_entry, cur_path in find(dictionary):
print(cur_path)
print(meta_entry)
С принтами:
['Client', 'MetaData', 'MetaEntry']
[{'Key': 'status', 'Value': 'Active'}, {'Key': 'first_day_of_week', 'Value': 'Monday'}, {'Key': 'default_induction_expiry', 'Value': '0'}]
Комментарии:
1. есть ли способ получить ключи-путь в этой функции , например: словарь[‘Клиент’][‘Метаданные’][‘MetaEntry’]. подобный этому
Ответ №2:
приведенный ниже код будет обрабатывать ситуацию, когда «Клиент» будет заменен другой строкой
data = {"Tags": [], "ObjectId": "ab9c6448-85fe-eb11-b563-281878c3a7fe", "kkk": {"MetaData": {
"MetaEntry": [{"Key": "status", "Value": "Active"}, {"Key": "first_day_of_week", "Value": "Monday"},
{"Key": "default_induction_expiry", "Value": "0"}]}, "RelatedLinks": [], "Tags": [],
"ObjectId": "6cf54386-d81a-eb11-9fb4-281878b13795",
"Type": "Artifice.Web.Data.Entities.Client",
"Name": "Amco Logictics "}}
for k,v in data.items():
if isinstance(v,dict) and 'MetaData' in v:
print(f'{k} points to metadata')
выход
kkk points to metadata