按照键到键映射转换Python字典键

时间:2019-07-18 08:22:40

标签: python dictionary mapping

根据密钥映射,我需要一个用于将Python dict的密钥转换为其他密钥的函数。例如,假设我有映射:

{
    "olk_key_1": "new_key_1",
    "olk_key_2": "new_key_2",
    "olk_key_3": "new_key_3",
}

还有dict

{
    "old_key_1": 1,
    "old_key_2": 2,
    "old_key_3": 3,
}

我想要的是:

{
    "new_key_1": 1,
    "new_key_2": 2,
    "new_key_3": 3,
}

这方面的棘手部分是函数必须支持任何嵌套结构的排序

其中包括:

    dict中的
  • dict s
  • dict中的
  • list s
  • list中的
  • dict s

我目前的工作功能很丑。任何看起来更好(随意重构我的代码)的东西都将被视为答案。

def map_keys(self, data, mapping):
    """
    This function converts the data dictionary into another one with different keys, as specified by the mapping
    parameter
    :param data: The dictionary to be modified
    :param mapping: The key mapping
    :return: A new dictionary with different keys
    """
    new_data = data.copy()
    if isinstance(new_data, list):
        new_data = {"tmp_key": new_data}
        mapping.update({"tmp_key": "key_tmp"})
    iterate = list(new_data.items())
    for key, value in iterate:
        if isinstance(value, list) and isinstance(value[0], dict):
            new_list = []
            for item in new_data[key]:
                new_list.append(self.map_keys(item, mapping))
            new_data[mapping[key]] = new_list
        else:
            new_data[mapping[key]] = value
        new_data.pop(key)
    if "key_tmp" in new_data:
        new_data = new_data["key_tmp"]
    return new_data

编辑

作为一个例子,该函数应该能够转换输入(例如(故意过度卷积)):

[
    {
        "a": 1,
        "b":[
                {
                    "c": 1,
                    "d": 1
                },
                {
                    "e": 1,
                    "f": 1
                }
            ]
    },
    {
        "g": {
            "h": {
                "i": 1,
            },
            "j": {
                "k": 1  
            }
        }
    }
]

1 个答案:

答案 0 :(得分:3)

您可以将json.load()与自定义objects_pairs_hook参数(doc)结合使用:

mapping_d = {
    "old_key_1": "new_key_1",
    "old_key_2": "new_key_2",
    "old_key_3": "new_key_3",
}

d = {
    "old_key_1": 1,
    "old_key_2": 2,
    "old_key_3": [
        {"old_key_1": 4},
        {"old_key_2": 5}
    ],
}

import json

def fn(obj):
    rv = dict([(mapping_d.get(n, n), v) for n, v in obj])
    return rv

d = json.loads(json.dumps(d), object_pairs_hook=fn)
from pprint import pprint
pprint(d, width=30)

打印:

{'new_key_1': 1,
 'new_key_2': 2,
 'new_key_3': [{'new_key_1': 4},
               {'new_key_2': 5}]}