使用映射字典更改字典的键

4
我可以帮您翻译成中文。以下是需要翻译的内容:

我想通过传递一个映射字典的函数来替换字典的键名,该函数还要替换嵌套键。问题在于,我有多个嵌套字典中命名为“id”的键,并且我想将这些“id”重命名为特定名称。

初始字典:

initial_dict = {'id': 1, 'netAmount': 10.2, 'modifiedOn': '2017-01-01',
                    'statusId': 3, 'approvalStateId': 3, 'approvalState': {'id': 3,'name':'Approved'}}

映射字典:

 mapping_dict = {'id': 'pr_id', 'netAmount': 'net_amount', 'modifiedOn': 'modified_date',
                'statusId': 'status_id', 'approvalStateId': 'approval_id','approvalState':{'id':'approv_id'}}

字典的期望输出结果:

    output_dict = {'pr_id': 1, 'net_amount': 10.2, 'modified_date': '2017-01-01',
                    'status_id': 3, 'approval_id': 3, 'approvalState': {'approv_id': 3, 'name': 'Approved'}}

我所做的是这样的,但它只替换字典第一层级的键,如果我尝试在映射字典中设置嵌套键,则会出现错误。

def map_fields(obj):
    new_obj = {}
    mapping_dict = {'id': 'pr_id', 'netAmount': 'net_amount', 'modifiedOn': 'modified_date',
                    'statusId': 'status_id', 'approvalStateId': 'approval_id','approvalState':{'id':'approv_id'}}
    for key in obj.keys():
        if key in mapping_dict:
            new_key = mapping_dict[key]
        else:
            new_key = key
        new_obj[new_key] = obj[key]
    return new_obj

你知道如何做吗?感谢。
2个回答

3
您需要一个递归函数来遍历嵌套字典。关键在于,在递归时,您需要同时传递子字典和子映射字典。
请注意,映射字典的结构特定于此问题,并且不允许您更改嵌套字典的键 - 您需要重新构造存储映射的方式才能实现这一点。
以下内容应该可以满足您的需求(添加了打印语句以帮助了解运行时的逻辑):
def map_fields(init_dict, map_dict, res_dict=None):

    res_dict = res_dict or {}
    for k, v in init_dict.items():
        print("Key: ", k)
        if isinstance(v, dict):
            print("value is a dict - recursing")
            v = map_fields(v, map_dict[k])
        elif k in map_dict.keys():
            print("Remapping:", k, str(map_dict[k]))
            k = str(map_dict[k])
        res_dict[k] = v
    return res_dict

print(map_fields(initial_dict, mapping_dict))

1

如果您想获得相同的结果,但不想使用嵌套映射字典,可以这样做:

mapping_dict = {'id': 'pr_id', 'netAmount': 'net_amount', 'modifiedOn': 'modified_date',
            'statusId': 'status_id', 'approvalStateId': 'approval_id', 'id':'approv_id'}

(即'id'/'approv_id'未嵌套在'approvalState'中)

您可以使用略有不同的函数:

def map_fields(init_dict, map_dict, res_dict=None):
    res_dict = res_dict or {}
    for k, v in init_dict.items():
        if isinstance(v, dict):
            v = map_fields(v, map_dict)
        if k in map_dict.keys():
            k = str(map_dict[k])
        res_dict[k] = v
    return res_dict

如果键“approvalState”也要映射(例如到类似“resultState”的内容),那么这将特别有用,即如果您的结果需要为:
output_dict = {'pr_id': 1, 'net_amount': 10.2, 'modified_date': '2017-01-01',
     'status_id': 3, 'approval_id': 3, 'resultState': {'approv_id': 3, 'name': 'Approved'}}

在这种情况下,您只需要在映射字典中添加键/值对“approvalState”/“resultState”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接