【问题标题】:Convert Python dictionary keys following a key-to-key mapping按照键对键映射转换 Python 字典键
【发布时间】:2019-07-18 16:40:07
【问题描述】:

根据键映射,我需要一个用于将 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,
}

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

这包括:

  • dicts of dicts
  • dicts of lists
  • lists of dicts

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

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  
            }
        }
    }
]

【问题讨论】:

  • 这个问题可能更适合codereview?
  • 看到了,但该答案不考虑列表。
  • @OcasoProtal 确实如此。虽然我有点希望有一个单行的 Python 魔术,但我不知道:p
  • 哪个词典需要更新?嵌套结构中的所有字典?还是只是顶级词典?这不适用于哪种情况:new_dict = { key_map[key]: val for key, val in old_dict.items() }

标签: python dictionary mapping


【解决方案1】:

您可以将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}]}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-27
    • 2016-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多