繁体   English   中英

动态创建嵌套字典

[英]Dynamically create nested dictionary

作为一个简化的例子,假设我有以下字典,它告诉我公司不同地点的员工人数:

start_dict = {
    "/BUILDING_A/FLOOR_3/ROOM_12": 3, 
    "/BUILDING_A/FLOOR_3/ROOM_15": 4,
    "/BUILDING_A/FLOOR_4/ROOM_3": 2,
    "/BUILDING_B/FLOOR_1": 5,
    "/BUILDING_B/FLOOR_2": 3,
    "/BUILDING_C": 25,
    "/BUILDING_D": 32,
}

每个字典键都是一个带有一个或多个斜线分隔元素的字符串。 在我的真实数据中,每个键都可以包含任意数量的元素。

我希望将此起始字典转换为嵌套字典。 期望的结果如下所示:

{
    "BUILDING_A": {
        "FLOOR_3": {
            "ROOM_12": 3,
            "ROOM_15": 4,
        },
        "FLOOR_4": {
            "ROOM_3": 2
        },
    },
    "BUILDING_B": {
        "FLOOR_1": 5,
        "FLOOR_2": 3,
    },
    "BUILDING_C": 25,
    "BUIDLING_D": 32,
}

到目前为止尝试过

我已尝试调整此答案,但无法使其正常工作。 这是我想出的代码:

result_dict = {}
for key, value in start_dict.items():
    new_keys = key.lstrip("/").split("/")
    current_dict = result_dict
    for new_key in new_keys[:-1]:
        current_dict = current_dict.get(new_key, {})
    current_dict[new_keys[-1]] = value

它给出了以下作为result_dict

{'BUILDING_C': 25, 'BUILDING_D': 32}

您的代码的问题是current_dict = current_dict.get(new_key, {})行。 如果密钥不存在,则创建新的 object,但不要将其分配给原始 object

所以工作代码是:

result_dict = {}
for key, value in start_dict.items():
    new_keys = key.lstrip("/").split("/")
    current_dict = result_dict
    for new_key in new_keys[:-1]:
        if new_key not in current_dict:
            current_dict[new_key] = {}
        current_dict = current_dict[new_key]
    current_dict[new_keys[-1]] = value

完整的演示(如果您点击Run the snippet ,请耐心等待:

 <script defer src="https://pyscript.net/unstable/pyscript.js"></script> <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" /> <div id="out"></div> <py-script output="out" style="display: none"> from pprint import pprint start_dict = { "/BUILDING_A/FLOOR_3/ROOM_12": 3, "/BUILDING_A/FLOOR_3/ROOM_15": 4, "/BUILDING_A/FLOOR_4/ROOM_3": 2, "/BUILDING_B/FLOOR_1": 5, "/BUILDING_B/FLOOR_2": 3, "/BUILDING_C": 25, "/BUILDING_D": 32, } result_dict = {} for key, value in start_dict.items(): new_keys = key.lstrip("/").split("/") current_dict = result_dict for new_key in new_keys[:-1]: if new_key not in current_dict: current_dict[new_key] = {} current_dict = current_dict[new_key] current_dict[new_keys[-1]] = value pprint(result_dict) </py-script>

如果字典中尚未包含new_key ,您想在此处插入它:

current_dict = current_dict.get(new_key, {})

通过将该行更改为

current_dict = current_dict.setdefault(new_key, {})

结果:

{
    "BUILDING_A": {
        "FLOOR_3": {
            "ROOM_12": 3,
            "ROOM_15": 4
        },
        "FLOOR_4": {
            "ROOM_3": 2
        }
    },
    "BUILDING_B": {
        "FLOOR_1": 5,
        "FLOOR_2": 3
    },
    "BUILDING_C": 25,
    "BUILDING_D": 32
}

尝试:

start_dict = {
    "/BUILDING_A/FLOOR_3/ROOM_12": 3,
    "/BUILDING_A/FLOOR_3/ROOM_15": 4,
    "/BUILDING_A/FLOOR_4/ROOM_3": 2,
    "/BUILDING_B/FLOOR_1": 5,
    "/BUILDING_B/FLOOR_2": 3,
    "/BUILDING_C": 25,
    "/BUILDING_D": 32,
}


def to_dict(k, v):
    keys = k.strip("/").split("/", maxsplit=1)
    if len(keys) == 1:
        return {keys[0]: v}
    return {keys[0]: to_dict(keys[1], v)}


# merge to d1
def merge(d1, d2):
    for k, v in d2.items():
        if k in d1:
            merge(d1[k], v)
        else:
            d1[k] = v


out = {}
for k, v in start_dict.items():
    merge(out, to_dict(k, v))

print(out)

印刷:

{
    "BUILDING_A": {
        "FLOOR_3": {"ROOM_12": 3, "ROOM_15": 4},
        "FLOOR_4": {"ROOM_3": 2},
    },
    "BUILDING_B": {"FLOOR_1": 5, "FLOOR_2": 3},
    "BUILDING_C": 25,
    "BUILDING_D": 32,
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM