Python 递归枚举JSON层次结构父/子字典

Python 递归枚举JSON层次结构父/子字典,python,json,dictionary,recursion,enumerate,Python,Json,Dictionary,Recursion,Enumerate,我希望将未知结构的JSON层次结构展平到字典中,捕获字典结果中的完整键层次结构以唯一地标识它 到目前为止,我能够递归地打印所有父/子节点的key:value对,但我遇到了问题: (1) 了解如何为递归(子)执行传递父层次结构键,然后在退出子键时重置它 (2) 写入单个字典结果-当我在递归函数中定义字典时,我最终创建了多个字典。。。我是否需要将此函数包装在主函数中以避免此问题 谢谢 # flatten/enumerate example I'm using with open('_json\\f

我希望将未知结构的JSON层次结构展平到字典中,捕获字典结果中的完整键层次结构以唯一地标识它

到目前为止,我能够递归地打印所有父/子节点的key:value对,但我遇到了问题:

(1) 了解如何为递归(子)执行传递父层次结构键,然后在退出子键时重置它

(2) 写入单个字典结果-当我在递归函数中定义字典时,我最终创建了多个字典。。。我是否需要将此函数包装在主函数中以避免此问题

谢谢

# flatten/enumerate example I'm using

with open('_json\\file.json') as f:
    data = json.load(f)

def parse_json_response(content):

    if len (content.keys()) > 1 :
        for key, value in content.items():
            if type(value) is dict:
                parse_json_response(value)
            else:
                print('{}:{}'.format(key,value))
    else:
        print(value)

if __name__ == '__main__':
    parse_json_response(data)
请尝试以下操作:

test = {
    "ID": "12345",
    "fields": {
        "firstName": "John",
        "lastName": "Smith",
        "DOB": "1980-01-01",
        "phoneLand": "610292659333",
        "address": {
            "residential": {
                "line1": "Unit 4",
                "line2": "3 Main st"
            }
        }
    }
}

def func(d, parent=""):
    for key, value in d.items():
        if isinstance(value, dict):
            func(value, parent=parent+key+".")
        else:
            print(f"{parent+key} = {value}")


func(test)
结果:

ID = 12345
fields.firstName = John
fields.lastName = Smith
fields.DOB = 1980-01-01
fields.phoneLand = 610292659333
fields.address.residential.line1 = Unit 4
fields.address.residential.line2 = 3 Main st
请尝试以下操作:

test = {
    "ID": "12345",
    "fields": {
        "firstName": "John",
        "lastName": "Smith",
        "DOB": "1980-01-01",
        "phoneLand": "610292659333",
        "address": {
            "residential": {
                "line1": "Unit 4",
                "line2": "3 Main st"
            }
        }
    }
}

def func(d, parent=""):
    for key, value in d.items():
        if isinstance(value, dict):
            func(value, parent=parent+key+".")
        else:
            print(f"{parent+key} = {value}")


func(test)
结果:

ID = 12345
fields.firstName = John
fields.lastName = Smith
fields.DOB = 1980-01-01
fields.phoneLand = 610292659333
fields.address.residential.line1 = Unit 4
fields.address.residential.line2 = 3 Main st

通过跟踪父字典并在正确的位置递归,可以创建展开字典(而不仅仅是打印值)。这可能看起来像:

d = {
    "ID": "12345",
    "fields": {
        "firstName": "John",
        "lastName": "Smith",
        "DOB": "1980-01-01",
        "phoneLand": "610292659333",
        "address": {
            "residential": {
                "line1": "Unit 4",
                "line2": "3 Main st"
            }
        }
    }
}

def flattenDict(d, parent=None):
    ret = {}
    for k, v in d.items():
        if parent:
            k = f'{parent}.{k}'
        if isinstance(v, dict):
            ret.update(flattenDict(v, k))
        else:
            ret[k] = v
    return ret

flat = flattenDict(d)
flat
将:

{'ID': '12345',
 'fields.firstName': 'John',
 'fields.lastName': 'Smith',
 'fields.DOB': '1980-01-01',
 'fields.phoneLand': '610292659333',
 'fields.address.residential.line1': 'Unit 4',
 'fields.address.residential.line2': '3 Main st'}
您还可以将输出安排为生成元组的生成器。然后,您可以将其传递给
dict()
,以获得相同的结果:

def flattenDict(d):
    for k, v in d.items():
        if isinstance(v, dict):
            yield from ((f'{k}.{kk}', v) for kk, v in flattenDict(v))
        else:
            yield (k, v)

dict(flattenDict(d))

通过跟踪父字典并在正确的位置递归,可以创建展开字典(而不仅仅是打印值)。这可能看起来像:

d = {
    "ID": "12345",
    "fields": {
        "firstName": "John",
        "lastName": "Smith",
        "DOB": "1980-01-01",
        "phoneLand": "610292659333",
        "address": {
            "residential": {
                "line1": "Unit 4",
                "line2": "3 Main st"
            }
        }
    }
}

def flattenDict(d, parent=None):
    ret = {}
    for k, v in d.items():
        if parent:
            k = f'{parent}.{k}'
        if isinstance(v, dict):
            ret.update(flattenDict(v, k))
        else:
            ret[k] = v
    return ret

flat = flattenDict(d)
flat
将:

{'ID': '12345',
 'fields.firstName': 'John',
 'fields.lastName': 'Smith',
 'fields.DOB': '1980-01-01',
 'fields.phoneLand': '610292659333',
 'fields.address.residential.line1': 'Unit 4',
 'fields.address.residential.line2': '3 Main st'}
您还可以将输出安排为生成元组的生成器。然后,您可以将其传递给
dict()
,以获得相同的结果:

def flattenDict(d):
    for k, v in d.items():
        if isinstance(v, dict):
            yield from ((f'{k}.{kk}', v) for kk, v in flattenDict(v))
        else:
            yield (k, v)

dict(flattenDict(d))

您可以发布您的示例json吗?{“ID”:“12345”,“fields”:{“firstName”:“John”,“lastName”:“Smith”,“DOB”:“1980-01-01”,“phoneLand”:“610292659333”,“address”:{“residential”:{“line1”:“Unit 4”,“line2”:“3 Main st”}}您可以发布您的示例json吗?{“ID”:“12345”,“fields”:{“firstName”:“John”,“lastName”:“Smith”,“DOB”:“1980-01-01”,“phoneLand”:“610292659333”,“address”:{“residential”:{“line1”:“Unit 4”,“line2”:“3 Main st”}}谢谢,这也很好,你们同时回答了这个问题:)谢谢@redsky-只是制作新的dict和从函数打印之间的区别。谢谢,这也很好,你们同时回答了这个问题:)谢谢@redsky-只是制作新的dict和从函数打印之间的区别。