我有一个包含匹配站点和匹配设备的词典列表,我想按站点然后按设备重新组合这些词典。
我添加了一个示例输出字典和一个所需的字典。
我想我可以使用 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/