首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python -将字典的列表重新组合成两个嵌套的字典列表?

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

Stack Overflow用户
提问于 2019-05-08 10:04:06
回答 2查看 88关注 0票数 3

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

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

我想我可以用迭代工具来做多个有效的组--我确实有这些组--但是我不知道如何将它们合并,或者这是否是最有效的方法

迭代工具尝试:

代码语言:javascript
运行
复制
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:

原始数据

代码语言:javascript
运行
复制
[
    {
        "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"
    },             
]

期望的dict

代码语言:javascript
运行
复制
[
    { 
    "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",
            }
        }
    }
]
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-08 10:14:09

为此,使用双collections.defaultdict,其中包含一个最高级的列表,并在项目上循环,弹出“键”,这样它们就不会出现在最终数据中:

代码语言:javascript
运行
复制
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以消除特殊dicts的表示):

代码语言:javascript
运行
复制
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-based解决方案也可以工作,但只有在相同的键是连续的情况下才能工作。否则,它会创建几个组,而不是您想要的。

票数 2
EN

Stack Overflow用户

发布于 2019-05-08 10:23:11

可以使用defaultdictitertools.groupby

代码语言:javascript
运行
复制
import itertools
from collections import defaultdict
res = defaultdict(dict)

for x, g in itertools.groupby(bgp_data_query, key=lambda x: x["location"]):
    for d, f in itertools.groupby(g, key=lambda x: x["device_name"]):
        res[x][d] = [{k:v}  for z in f for k, v in z.items() if k not in {"location", "device_name"}]

print(dict(res))

输出:

代码语言:javascript
运行
复制
{'London': {'LON-EDGE': [{'bgp_peer_as': '1'},
   {'bgp_routes': '0'},
   {'circuit_name': 'MPLS'},
   {'bgp_session': '3:35'},
   {'service_status': 'Down'},
   {'bgp_peer_as': '3'},
   {'bgp_routes': '100'},
   {'circuit_name': 'MPLS 02'},
   {'bgp_session': '4:25'},
   {'service_status': 'UP'}],
  'LON-INT-GW': [{'bgp_peer_as': '18'},
   {'bgp_routes': '1'},
   {'circuit_name': 'INTERNET'},
   {'bgp_session': '1:25'},
   {'service_status': 'UP'}]},
 'Manchester': {'MAN-EDGE': [{'bgp_peer_as': '45'},
   {'bgp_routes': '1'},
   {'circuit_name': 'MPLS 01'},
   {'bgp_session': '1:25'},
   {'service_status': 'UP'}],
  'MAN-INT-GW': [{'bgp_peer_as': '20'},
   {'bgp_routes': '1'},
   {'circuit_name': 'INTERNET'},
   {'bgp_session': '1:25'},
   {'service_status': 'UP'},
   {'bgp_peer_as': '20'},
   {'bgp_routes': '1'},
   {'circuit_name': 'INTERNET 02'},
   {'bgp_session': '1:25'},
   {'service_status': 'UP'}]}}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56038162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档