Проверьте наличие ключа во всем списке или продиктуйте его в python
Я создаю dict в python, и этот dict может включать в себя списки и поддикты. Если я хочу проверить, существует ли ключ в каком-либо из этих диктовок, я сначала до него докажу, и только тогда я могу проверить, существует ли ключ или нет. Но есть ли способ, которым я могу проверить существование ключа, используя родительский dict, только означает, что если родительский dict имеет дочерние dict, тогда поиск переходит на каждый уровень и позволяет мне знать, существует ли ключ во всем dict или нет, и затем, используя этот ключ, я могу вставьте или удалите элементы в этой записи, которая включает этот ключ.
например, у меня есть это
[
{
'groupName': u'MainMenu_1',
'menuItems': [
{
'action': u'/home\r\n',
'sub_1': [
],
'id': 1L,
'name': u'Home\r\n'
},
{
'action': u'/inventory',
'sub_2': [
],
'id': 2L,
'name': u'Inventory\r\n'
},
{
'action': u'/accounting\r\n',
'sub_3': [
{
'action': u'/gl\r\n',
'name': u'GL\r\n',
'sub_4': [
]
},
{
'action': u'/ap\r\n',
'name': u'AP\r\n',
'sub_5': [
]
},
{
'action': u'/ar\r\n',
'sub_6': [
],
'name': u'AR\r\n'
}
],
'id': 3L,
'name': u'Accounting\r\n'
},
{
'action': u'/crm\r\n',
'sub_8': [
],
'id': 8L,
'name': u'CRM\r\n'
}
]
},
{
'groupName': u'MainMenu_2',
'menuItems': [
{
'action': u'/iv-receive\r\n',
'sub_9': [
],
'id': 9L,
'name': u'Receiving\r\n'
},
{
'action': u'/iv-shipping\r\n',
'sub_10': [
],
'id': 10L,
'name': u'Shipping\r\n'
}
]
}
]
Теперь, если в приведенном выше примере я хочу найти любой ключ, такой как sub_1, sub_3, sub_6, то как я могу найти этот ключ
2 ответа
Мы можем искать все подходящие словари рекурсивно. Следующая реализация добавляет все ссылки таких словарей в список found
:
def recursive_search(items, key):
found = []
for item in items:
if isinstance(item, list):
found += recursive_search(item, key)
elif isinstance(item, dict):
if key in item:
found.append(item)
found += recursive_search(item.values(), key)
return found
found = recursive_search(items, 'sub_9')
def flatten(obj):
if isinstance(obj, list):
result = set()
for e in obj:
result = result.union(flatten(e))
return result
elif isinstance(obj, dict):
return set(obj.keys()) | flatten(obj.values())
else:
return {obj}
В качестве альтернативы вы можете сгладить список / словарь в набор и выполнить столько поисков, сколько захотите.
print(flatten(lst))
set([1, 2, 3, u'/inventory', 8, 9, 'menuItems', u'/home\r\n', u'/ar\r\n', u'AP\r\n', u'/accounting\r\n', 'id', u'MainMenu_2', u'Receiving\r\n', u'Home\r\n', u'MainMenu_1', u'/iv-shipping\r\n', 'groupName', 10, u'AR\r\n', u'Accounting\r\n', u'/ap\r\n', u'Inventory\r\n', u'CRM\r\n', u'/crm\r\n', u'/iv-receive\r\n', 'sub_10', u'GL\r\n', u'Shipping\r\n', 'name', 'sub_2', 'sub_3', 'sub_1', 'sub_6', 'sub_4', 'sub_5', 'action', 'sub_8', 'sub_9', u'/gl\r\n'])