Python - 将字典列表重新组合为两个嵌套的字典列表?

标签 python dictionary

我有一个包含匹配站点和匹配设备的词典列表,我想按站点然后按设备重新组合这些词典。

我添加了一个示例输出字典和一个所需的字典。

我想我可以使用 itertools 做多个组,这很有效我确实有这些组,但我不确定如何合并它们,或者这是否是最有效的方法

itertools 尝试:

site_groups = itertools.groupby(bgp_data_query, lambda i: i['location'])
for key, site in site_groups:
    device_groups = itertools.groupby(site, lambda i: i['device_name'])
    for key, device in site_groups:

原始数据

[
    {
        "bgp_peer_as": "1",
        "bgp_session": "3:35",
        "bgp_routes": "0",
        "service_status": "Down",
        "location": "London",
        "circuit_name": "MPLS",
        "device_name": "LON-EDGE",
        "timestamp" : "2019-5-8 12:30:00"
    },
    {
        "bgp_peer_as": "3",
        "bgp_session": "4:25",
        "bgp_routes": "100",
        "service_status": "UP",
        "location": "London",
        "circuit_name": "MPLS 02",
        "device_name": "LON-EDGE",
        "timestamp" : "2019-5-8 12:30:00"
    },    
    {
        "bgp_peer_as": "18",
        "bgp_session": "1:25",
        "bgp_routes": "1",
        "service_status": "UP",
        "location": "London",
        "circuit_name": "INTERNET",
        "device_name": "LON-INT-GW",
        "timestamp" : "2019-5-8 12:31:00"
    },  
    {
        "bgp_peer_as": "20",
        "bgp_session": "1:25",
        "bgp_routes": "1",
        "service_status": "UP",
        "location": "Manchester",
        "circuit_name": "INTERNET",
        "device_name": "MAN-INT-GW",
        "timestamp" : "2019-5-8 12:20:00"
    },     
    {
        "bgp_peer_as": "20",
        "bgp_session": "1:25",
        "bgp_routes": "1",
        "service_status": "UP",
        "location": "Manchester",
        "circuit_name": "INTERNET 02",
        "device_name": "MAN-INT-GW",
        "timestamp" : "2019-5-8 12:20:00"
    }, 
    {
        "bgp_peer_as": "45",
        "bgp_session": "1:25",
        "bgp_routes": "1",
        "service_status": "UP",
        "location": "Manchester",
        "circuit_name": "MPLS 01",
        "device_name": "MAN-EDGE",
        "timestamp" : "2019-5-8 12:21:00"
    },             
]

想要的字典

[
    { 
    "London": { 
        "LON-EDGE": {
            "bgp_peer_as": "1",
            "bgp_session": "3:35",
            "bgp_routes": "0",
            "service_status": "DOWN",
            "circuit_name": "MPLS",
            },
            {
            "bgp_peer_as": "1",
            "bgp_session": "4:25",
            "bgp_routes": "100",
            "service_status": "UP",
            "circuit_name": "MPLS 02",
            }
        },
        { 
        "LON-INT-GW" : {
            "bgp_peer_as": "18",
            "bgp_session": "1:25",
            "bgp_routes": "1",
            "service_status": "UP",
            "circuit_name": "INTERNET",
            }
        }
    }
],
[
    { 
    "Manchester": { 
        "MAN-EDGE": {
            "bgp_peer_as": "45",
            "bgp_session": "1:25",
            "bgp_routes": "1",
            "service_status": "UP",
            "circuit_name": "MPLS 01",
            }
        },
        {
        "MAN-INT-GW": {
            "bgp_peer_as": "20",
            "bgp_session": "1:25",
            "bgp_routes": "1",
            "service_status": "UP",
            "circuit_name": "INTERNET",
            },
            {
            "bgp_peer_as": "20",
            "bgp_session": "1:25",
            "bgp_routes": "1",
            "service_status": "UP",
            "circuit_name": "INTERNET 02",
            }
        }
    }
]

最佳答案

为此,在最深层次使用带有列表的双重 collections.defaultdict,并在项目上循环,弹出“键”,这样它们就不会出现在最终数据中:

result = collections.defaultdict(lambda :collections.defaultdict(list))

for d in raw_dict:
    location = d.pop("location")
    device_name = d.pop("device_name")
    result[location][device_name].append(d)

结果与您的数据(转储为 json 以摆脱特殊字典的表示):

import json
print(json.dumps(result,indent=4))

{
    "Manchester": {
        "MAN-INT-GW": [
            {
                "bgp_routes": "1",
                "service_status": "UP",
                "bgp_peer_as": "20",
                "circuit_name": "INTERNET",
                "bgp_session": "1:25"
            },
            {
                "bgp_routes": "1",
                "service_status": "UP",
                "bgp_peer_as": "20",
                "circuit_name": "INTERNET 02",
                "bgp_session": "1:25"
            }
        ],
        "MAN-EDGE": [
            {
                "bgp_routes": "1",
                "service_status": "UP",
                "bgp_peer_as": "45",
                "circuit_name": "MPLS 01",
                "bgp_session": "1:25"
            }
        ]
    },
    "London": {
        "LON-EDGE": [
            {
                "bgp_routes": "0",
                "service_status": "Down",
                "bgp_peer_as": "1",
                "circuit_name": "MPLS",
                "bgp_session": "3:35"
            },
            {
                "bgp_routes": "100",
                "service_status": "UP",
                "bgp_peer_as": "3",
                "circuit_name": "MPLS 02",
                "bgp_session": "4:25"
            }
        ],
        "LON-INT-GW": [
            {
                "bgp_routes": "1",
                "service_status": "UP",
                "bgp_peer_as": "18",
                "circuit_name": "INTERNET",
                "bgp_session": "1:25"
            }
        ]
    }
}

请注意,基于itertools.groupby 的解决方案也可以工作,但前提是相同的键连续。否则它会创建多个组,而不是您想要的。

关于Python - 将字典列表重新组合为两个嵌套的字典列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56038162/

相关文章:

python - 在 PyQt 中使用计时器更新标签

python - 求和范围的时间复杂度

python - 通过索引访问 collections.OrderedDict 中的项目

java - 一个方法如何可以有不同数量的参数?

python - 如何从任意深度嵌套的字典中删除

python - 在 pandas 数据帧上滚动 720 分钟

python - 如何在 DataFrame 中找到包含特定列表的行

python - 如何在 Python 3 中正确处理字符串嵌入

Python:使用变量作为键访问字典

Python:有没有更好的方法来构造字典?