替换嵌套字典中的键

4
我有一个嵌套字典 {1: {2: {3: None}}} 和一个将嵌套字典中的键映射到一组值的字典,例如{1: x, 2: y, 3: z}。我想将嵌套字典转换为这种形式 {x: {y: {z: None}}}。我尝试了几个递归函数,但我不停地在循环和混淆自己。有什么最好的方法来实现这个目标吗?
嵌套深度是任意的。以上是一个简单的例子。

1
你有现成的代码吗? - Abhi V
3个回答

4

在构建具有新键的新字典时,您需要通过字典进行递归。请注意,如果其中包含有其他字典的列表或元组,则它们将不会被处理 - 您需要添加一些代码来处理它们。实际上,您可以在不构建新字典的情况下完成此操作,但我认为这种方式更简单。

od = { 1: { 2: { 3: None }}}
kd = { 1: 'x', 2: 'y', 3: 'z' }

def replace_keys(old_dict, key_dict):
    new_dict = { }
    for key in old_dict.keys():
        new_key = key_dict.get(key, key)
        if isinstance(old_dict[key], dict):
            new_dict[new_key] = replace_keys(old_dict[key], key_dict)
        else:
            new_dict[new_key] = old_dict[key]
    return new_dict

nd = replace_keys(od, kd)
print nd

输出:

{'x': {'y': {'z': None}}}

2

接受的答案不支持字典列表,需要添加完整功能。

@bilentor,

od = {'name': 'John', '1': [{'name': 'innername'}]}
kd = { 'name': 'cname', '1': '2', 3: 'z' }

def replace_keys(data_dict, key_dict):
    new_dict = { }
    if isinstance(data_dict, list):
        dict_value_list = list()
        for inner_dict in data_dict:
            dict_value_list.append(replace_keys(inner_dict, key_dict))
        return dict_value_list
    else:
        for key in data_dict.keys():
            value = data_dict[key]
            new_key = key_dict.get(key, key)
            if isinstance(value, dict) or isinstance(value, list):
                new_dict[new_key] = replace_keys(value, key_dict)
            else:
                new_dict[new_key] = value
        return new_dict

nd = replace_keys(od, kd)
print(nd)

整个函数也可以使用推导式来构建,使其更加简洁:def replace_keys(data_dict, key_dict): if isinstance(data_dict, list): return [replace_keys(l, key_dict) for l in data_dict] else: return {key_dict.get(key, key) : replace_keys(val, key_dict) if isinstance(val, dict) or isinstance(val, list) else val for key, val in data_dict.items()} - Freddy

0
你可以使用一个 NestedDict
from ndicts import NestedDict

d = {1: {2: {3: None}}}
replace = {1: 'x', 2: 'y', 3: 'z'}

def ndict_replace(ndict: dict, map: dict):
    nd = NestedDict(nd)
    new_nd = NestedDict()
    for key, value in nd.items():
        new_key = tuple(replace.get(k, k) for k in key)
        new_nd[new_key] = value
    return new_nd.to_dict()

>>> ndict_replace(d, replace)
{'x': {'y': {'z': None}}}

这个解决方案非常强大,可以与任何嵌套字典一起使用。

>>> d = {
        1: {2: {3: None}}, 
        3: {4: None},
        5: None
    }
>>> ndict_replace(d, replace)
{'x': {'y': {'z': None}}, 'z': {4: None}, 4: None}}

安装ndicts,请执行pip install ndicts


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