Часть вложенных ключей не выводится при бработке вложенного словаря

some_dict = {'tag': 'Building', 'attrib': ['CadastralNumber', 'DateCreated', 'FoundationDate'], 'CadastralBlock': {'tag': 'CadastralBlock', 'attrib': []}, 'ParentCadastralNumbers': {'tag': 'ParentCadastralNumbers', 'attrib': [], 'CadastralNumber': {'tag': 'CadastralNumber', 'attrib': []}}, 'PrevCadastralNumbers': {'tag': 'PrevCadastralNumbers', 'attrib': [], 'CadastralNumber': {'tag': 'CadastralNumber', 'attrib': []}}, 'PreviouslyPosted': {'tag': 'PreviouslyPosted', 'attrib': []}, 'Name': {'tag': 'Name', 'attrib': []}, 'ObjectType': {'tag': 'ObjectType', 'attrib': []}, 'AssignationBuilding': {'tag': 'AssignationBuilding', 'attrib': []}, 'ElementsConstruct': {'tag': 'ElementsConstruct', 'attrib': [], 'Material': {'tag': 'Material', 'attrib': ['Wall']}}, 'ExploitationChar': {'tag': 'ExploitationChar', 'attrib': ['YearBuilt', 'YearUsed']}, 'Floors': {'tag': 'Floors', 'attrib': ['Floors', 'UndergroundFloors']}, 'Area': {'tag': 'Area', 'attrib': []}, 'Location': {'tag': 'Location', 'attrib': ['AddressOrLocation'], 'FIAS': {'tag': 'FIAS', 'attrib': []}, 'OKATO': {'tag': 'OKATO', 'attrib': []}, 'KLADR': {'tag': 'KLADR', 'attrib': []}, 'OKTMO': {'tag': 'OKTMO', 'attrib': []}, 'PostalCode': {'tag': 'PostalCode', 'attrib': []}, 'RussianFederation': {'tag': 'RussianFederation', 'attrib': []}, 'Region': {'tag': 'Region', 'attrib': []}, 'District': {'tag': 'District', 'attrib': ['Name', 'Type']}, 'City': {'tag': 'City', 'attrib': ['Name', 'Type']}, 'UrbanDistrict': {'tag': 'UrbanDistrict', 'attrib': ['Name', 'Type']}, 'SovietVillage': {'tag': 'SovietVillage', 'attrib': ['Name', 'Type']}, 'Locality': {'tag': 'Locality', 'attrib': ['Name', 'Type']}, 'Street': {'tag': 'Street', 'attrib': ['Name', 'Type']}, 'Level1': {'tag': 'Level1', 'attrib': ['Type', 'Value']}, 'Level2': {'tag': 'Level2', 'attrib': ['Type', 'Value']}, 'Level3': {'tag': 'Level3', 'attrib': ['Type', 'Value']}, 'Apartment': {'tag': 'Apartment', 'attrib': ['Type', 'Value']}, 'Other': {'tag': 'Other', 'attrib': []}, 'Note': {'tag': 'Note', 'attrib': []}, 'ReadableAddress': {'tag': 'ReadableAddress', 'attrib': []}}, 'ObjectPermittedUses': {'tag': 'ObjectPermittedUses', 'attrib': [], 'ObjectPermittedUse': {'tag': 'ObjectPermittedUse', 'attrib': []}}, 'CadastralCost': {'tag': 'CadastralCost', 'attrib': ['Value'], 'DateValuation': {'tag': 'DateValuation', 'attrib': []}, 'DateEntering': {'tag': 'DateEntering', 'attrib': []}, 'DateApproval': {'tag': 'DateApproval', 'attrib': []}, 'ApplicationDate': {'tag': 'ApplicationDate', 'attrib': []}, 'RevisalStatementDate': {'tag': 'RevisalStatementDate', 'attrib': []}, 'ApplicationLastDate': {'tag': 'ApplicationLastDate', 'attrib': []}, 'ApprovalDocument': {'tag': 'ApprovalDocument', 'attrib': [], 'CodeDocument': {'tag': 'CodeDocument', 'attrib': []}, 'Name': {'tag': 'Name', 'attrib': []}, 'Series': {'tag': 'Series', 'attrib': []}, 'Number': {'tag': 'Number', 'attrib': []}, 'Date': {'tag': 'Date', 'attrib': []}, 'IssueOrgan': {'tag': 'IssueOrgan', 'attrib': []}, 'Desc': {'tag': 'Desc', 'attrib': []}}}, 'SubBuildings': {'tag': 'SubBuildings', 'attrib': [], 'SubBuilding': {'tag': 'SubBuilding', 'attrib': ['NumberRecord', 'DateCreated'], 'Area': {'tag': 'Area', 'attrib': []}, 'Encumbrances': {'tag': 'Encumbrances', 'attrib': [], 'Name': {'tag': 'Name', 'attrib': []}, 'Type': {'tag': 'Type', 'attrib': []}, 'Registration': {'tag': 'Registration', 'attrib': [], 'RightNumber': {'tag': 'RightNumber', 'attrib': []}, 'RegistrationDate': {'tag': 'RegistrationDate', 'attrib': []}}, 'Document': {'tag': 'Document', 'attrib': [], 'CodeDocument': {'tag': 'CodeDocument', 'attrib': []}, 'Name': {'tag': 'Name', 'attrib': []}, 'Series': {'tag': 'Series', 'attrib': []}, 'Number': {'tag': 'Number', 'attrib': []}, 'Date': {'tag': 'Date', 'attrib': []}, 'IssueOrgan': {'tag': 'IssueOrgan', 'attrib': []}, 'Desc': {'tag': 'Desc', 'attrib': []}}}}}, 'FlatsCadastralNumbers': {'tag': 'FlatsCadastralNumbers', 'attrib': [], 'CadastralNumber': {'tag': 'CadastralNumber', 'attrib': []}}, 'CarParkingSpacesCadastralNumbers': {'tag': 'CarParkingSpacesCadastralNumbers', 'attrib': [], 'CadastralNumber': {'tag': 'CadastralNumber', 'attrib': []}}, 'UnitedCadastralNumber': {'tag': 'UnitedCadastralNumber', 'attrib': [], 'CadastralNumber': {'tag': 'CadastralNumber', 'attrib': []}, 'Purpose': {'tag': 'Purpose', 'attrib': []}, 'Name': {'tag': 'Name', 'attrib': []}}, 'FacilityCadastralNumber': {'tag': 'FacilityCadastralNumber', 'attrib': [], 'CadastralNumber': {'tag': 'CadastralNumber', 'attrib': []}, 'Purpose': {'tag': 'Purpose', 'attrib': []}, 'Name': {'tag': 'Name', 'attrib': []}}, 'CulturalHeritage': {'tag': 'CulturalHeritage', 'attrib': [], 'InclusionEGROKN': {'tag': 'InclusionEGROKN', 'attrib': [], 'RegNum': {'tag': 'RegNum', 'attrib': []}, 'ObjCultural': {'tag': 'ObjCultural', 'attrib': []}, 'NameCultural': {'tag': 'NameCultural', 'attrib': []}}, 'AssignmentEGROKN': {'tag': 'AssignmentEGROKN', 'attrib': [], 'RegNum': {'tag': 'RegNum', 'attrib': []}, 'ObjCultural': {'tag': 'ObjCultural', 'attrib': []}, 'NameCultural': {'tag': 'NameCultural', 'attrib': []}}, 'RequirementsEnsure': {'tag': 'RequirementsEnsure', 'attrib': []}, 'Document': {'tag': 'Document', 'attrib': [], 'CodeDocument': {'tag': 'CodeDocument', 'attrib': []}, 'Name': {'tag': 'Name', 'attrib': []}, 'Series': {'tag': 'Series', 'attrib': []}, 'Number': {'tag': 'Number', 'attrib': []}, 'Date': {'tag': 'Date', 'attrib': []}, 'IssueOrgan': {'tag': 'IssueOrgan', 'attrib': []}, 'Desc': {'tag': 'Desc', 'attrib': []}}}}

def print_dict_recursive(d):
list = []
for i in d.items():
    if isinstance(i[1], dict):
        # print(i[1]['tag'], i[1]['attrib'])
        list.append(i[1]['tag'])

return list

list = print_dict_recursive(some_dict)
for i in list:
    print({i: print_dict_recursive(some_dict[i])})

Есть словарь с вложенной структурой пытаюсь выполнить проход по всей структуре и перебрать все пары {ключ: значение}. Приведенный выше код затрагивает только два уровня вложенности и выводит следующий результат:

{'CadastralBlock': []}
{'ParentCadastralNumbers': ['CadastralNumber']}
{'PrevCadastralNumbers': ['CadastralNumber']}
{'PreviouslyPosted': []}
{'Name': []}
{'ObjectType': []}
{'AssignationBuilding': []}
{'ElementsConstruct': ['Material']}
{'ExploitationChar': []}
{'Floors': []}
{'Area': []}
{'Location': ['FIAS', 'OKATO', 'KLADR', 'OKTMO', 'PostalCode', 'RussianFederation', 'Region', 'District', 'City', 'UrbanDistrict', 'SovietVillage', 'Locality', 'Street', 'Level1', 'Level2', 'Level3', 'Apartment', 'Other', 'Note', 'ReadableAddress']}
{'ObjectPermittedUses': ['ObjectPermittedUse']}
{'CadastralCost': ['DateValuation', 'DateEntering', 'DateApproval', 'ApplicationDate', 'RevisalStatementDate', 'ApplicationLastDate', 'ApprovalDocument']}
{'SubBuildings': ['SubBuilding']}
{'FlatsCadastralNumbers': ['CadastralNumber']}
{'CarParkingSpacesCadastralNumbers': ['CadastralNumber']}
{'UnitedCadastralNumber': ['CadastralNumber', 'Purpose', 'Name']}
{'FacilityCadastralNumber': ['CadastralNumber', 'Purpose', 'Name']}
{'CulturalHeritage': ['InclusionEGROKN', 'AssignmentEGROKN', 'RequirementsEnsure', 'Document']}

Process finished with exit code 0

При этом часть вложенных ключей не выведена по примеру выше (например ключ 'ApprovalDocument' и другие. На данном этапе зашел в тупик, прошу помощи знатоков.


Ответы (1 шт):

Автор решения: Stanislav Volodarskiy
import collections


def visit_dicts(d):
    q = collections.deque()
    result = []

    q.append(([], d))
    while q:
        target1, d = q.popleft()

        found = False
        for v in d.values():
            if isinstance(v, dict):
                if not found:
                    found = True
                    target2 = []
                    result.append((d['tag'], target2))
                q.append((target2, v))

        if not found:
            target1.append(d['tag'])

    return result

...

for tag, values in visit_dicts(some_dict):
    print(tag, values)
$ python temp.py
Building ['CadastralBlock', 'PreviouslyPosted', 'Name', 'ObjectType', 'AssignationBuilding', 'ExploitationChar', 'Floors', 'Area']
ParentCadastralNumbers ['CadastralNumber']
PrevCadastralNumbers ['CadastralNumber']
ElementsConstruct ['Material']
Location ['FIAS', 'OKATO', 'KLADR', 'OKTMO', 'PostalCode', 'RussianFederation', 'Region', 'District', 'City', 'UrbanDistrict', 'SovietVillage', 'Locality', 'Street', 'Level1', 'Level2', 'Level3', 'Apartment', 'Other', 'Note', 'ReadableAddress']
ObjectPermittedUses ['ObjectPermittedUse']
CadastralCost ['DateValuation', 'DateEntering', 'DateApproval', 'ApplicationDate', 'RevisalStatementDate', 'ApplicationLastDate']
SubBuildings []
FlatsCadastralNumbers ['CadastralNumber']
CarParkingSpacesCadastralNumbers ['CadastralNumber']
UnitedCadastralNumber ['CadastralNumber', 'Purpose', 'Name']
FacilityCadastralNumber ['CadastralNumber', 'Purpose', 'Name']
CulturalHeritage ['RequirementsEnsure']
ApprovalDocument ['CodeDocument', 'Name', 'Series', 'Number', 'Date', 'IssueOrgan', 'Desc']
SubBuilding ['Area']
InclusionEGROKN ['RegNum', 'ObjCultural', 'NameCultural']
AssignmentEGROKN ['RegNum', 'ObjCultural', 'NameCultural']
Document ['CodeDocument', 'Name', 'Series', 'Number', 'Date', 'IssueOrgan', 'Desc']
Encumbrances ['Name', 'Type']
Registration ['RightNumber', 'RegistrationDate']
Document ['CodeDocument', 'Name', 'Series', 'Number', 'Date', 'IssueOrgan', 'Desc']
→ Ссылка