Найти все ключи и ключи ключей во вложенном словаре

Я пытаюсь найти все атрибуты данных во вложенном словаре в Python. Некоторые объекты могут иметь несколько уровней в определении ключа. Как я могу найти заголовок таких сложных вложенных данных (если мы будем рассматривать как структуру таблицы). Здесь очень мало строк моих данных, чтобы посмотреть, как это выглядит:

{"MessageType": "SALES.HOLDCREATED", "Event": {"Id": "ZWbDoMKQw6HDjFzCo8KuwpNmwofCjl7Co8OPwpDCncOSXMOdccKTZVVWZWbCnA==", "RefInfo": {"TId": {"Id": "ZMKXwpbClsOhwpNiw5E="}, "UserId": {"Id": "wpzCksKWwpbCpMKTYsKeZMKZbA=="}, "SentUtc": "2013-04-28T16:59:48.6698042", "Source": 1}, "ItemId": {"Id": 116228}, "Quantity": 1, "ExpirationDate": "2013-04-29T", "Description": null}}
{"MessageType": "SALES.SALEITEMCREATED", "Event": {"Id": "ZWbDoMKQw6HDjFzCo8KuwpNmwofCjl7Co8OPwpDCncOSXMOdccKTwp3CiFZkZMKWwpfCpMKZ", "RefInfo": {"TId": {"Id": "ZGA="}, "UserId": {"Id": "ZMKj"}, "SentUtc": "2013-01-04T", "Source": 1}, "Code": {"Code": "074108235206"}, "Sku": {"Sku": "Con CS54"}}}
{"MessageType": "SALES.SALEITEMCREATED", "Event": {"Id": "ZWbDoMKQw6HDjFzCo8KuwpNmwofCjl7Co8OPwpDCncOSXMOdccKTZcKHVsKcwpjClsKXwqTCmQ==", "RefInfo": {"TId": {"Id": "ZGA="}, "UserId": {"Id": "ZMKj"}, "SentUtc": "2013-01-04T", "Source": 1}, "Code": {"Code": "4000000021"}, "Sku": {"Sku": "NFL-Wallet-MK-2201"}}}

Так как эти данные в формате Json, я сначала изменил формат и попытался найти ключ:

import json

data = []
with open("data.raw", "r") as f:
    for line in f:
        data.append(json.loads(line))

for lines in data:
    print(lines.keys())

но он дает мне dict_keys(['Event', 'MessageType']) для всех строк. Что мне нужно (для этих данных, которые я приложил) - это список, например:

'MessageType' 'Event_Id' 'Event_RefInfo_TId_Id'  'Event_RefInfo_UserId_Id' 'Event_RefInfo_SentUtc' 'Event_RefInfo_Source' 'Event_ItemId_Id' 'Event_ItemId_Quantity' 'Event_ItemId_ExpirationDate'     ...

Данные очень большие, и мне просто нужно выяснить, какие у меня есть атрибуты.

Ответ 1

Вам нужно будет пересечь вложенные dicts, ваш текущий подход только доходит до ключей корневого словаря.

Вы можете использовать следующую функцию генератора для поиска ключей и рекурсивно пересекать вложенные дикты:

import json 
from pprint import pprint

def find_keys(dct):
    for k, v in dct.items():
        if isinstance(v, dict):
            # traverse nested dict
            for x in find_keys(v):
                yield "{}_{}".format(k, x)
        else:
            yield k

Учитывая список словарей, полученных из вашего json-объекта, вы можете найти ключи в каждом dict и поместить их в набор, чтобы записи были уникальными:

s = set()
for d in json.loads(lst):
    s.update(find_keys(d))

pprint(s)

set(['Event_Code_Code',
     'Event_Description',
     'Event_ExpirationDate',
     'Event_Id',
     'Event_ItemId_Id',
     'Event_Quantity',
     'Event_RefInfo_SentUtc',
     'Event_RefInfo_Source',
     'Event_RefInfo_TId_Id',
     'Event_RefInfo_UserId_Id',
     'Event_Sku_Sku',
     'MessageType'])