如何解决如何在嵌套字典中合并具有相同键的值? 没有用
首先,我是Python编程的新手,因此深表感谢。我在合并来自不同词典的相同键值时遇到问题,因此它是单个键值对。我尝试了此处提供的许多解决方案,但似乎没有一个适合我的情况。我知道我做错了。输出来自解析两个单独的基于文本的配置。所有这些都以同一个巨型masterDict词典结尾。我可以更改它,以便每个文件生成一个单独的字典,但是我希望它可以扩展为最多4个嵌套字典。 0是第一个文件,1是第二个文件。这是字典的摘要版本。
masterDict = {0: {'access': {'interface GigabitEthernet0/1': ' switchport access vlan 532'},'description': {'interface GigabitEthernet0/1': ' description Printer'},'duplex': {'interface GigabitEthernet0/1': ' duplex half'},'speed': {'interface GigabitEthernet0/1': ' speed 10'},'trunk': {'interface GigabitEthernet0/1': 'switchport mode trunk'}},1: {'access': {'interface GigabitEthernet0/2': ' switchport access vlan 532'},'description': {'interface GigabitEthernet0/2': ' description Printer'},'duplex': {'interface GigabitEthernet0/2': ' duplex half'},'speed': {'interface GigabitEthernet0/2': ' speed 10'},'trunk': {'interface GigabitEthernet0/2': 'switchport mode trunk'}}}
我希望最终结果如下所示:
newMasterDict = {0: {'interface GigabitEthernet0/1': [' switchport access vlan 532',' description Printer',' duplex half',' speed 10','switchport mode trunk']},1: {'newDict': {'interface GigabitEthernet0/2': [' switchport access vlan 532','switchport mode trunk']}}}
请注意,键不会出现在每个词典中。有人可以指出正确的方向吗?非常感谢!
以下是masterDict的生成方式:
from ciscoconfparse import CiscoConfParse
from collections import defaultdict
homepath = 'c:/Users/c_eavila/Box/Projects/Environment1/'
pathList = ("testconfig.txt","testconfig2.txt")
queryList = ('description','speed','duplex')
swpModes = ("access","trunk")
masterDict = {}
masterDict2 = {}
for count,path in enumerate(pathList):
dictList = {}
loadParse = CiscoConfParse(config=homepath+path,ignore_blank_lines=True,syntax='ios')
for mode in swpModes:
if mode == "access":
parentParse = loadParse.find_parents_w_child(r'^interface',r'switchport mode '+mode)
accVlanParse = loadParse.find_children_w_parents(r'^interface',r'switchport access vlan')
accVlanDict = dict(zip(parentParse,accVlanParse))
dictList['access'] = accVlanDict
elif mode == "trunk":
v = 'switchport mode trunk'
parentParse = loadParse.find_parents_w_child(r'^interface',r'switchport mode '+mode)
trunkAllowedParse = loadParse.find_children_w_parents(r'^interface',r'switchport trunk allowed')
if trunkAllowedParse != []:
trunkAllowedDict = dict(zip(parentParse,trunkAllowedParse))
trunkDict = dict(zip(parentParse,'switchport mode trunk',))
dictList['trunkallowed'] = trunkAllowedDict
dictList['trunk'] = {k:v for k in trunkDict}
elif trunkAllowedParse == []:
trunkDict = dict(zip(parentParse,))
dictList['trunk'] = {k:v for k in trunkDict}
for query in queryList:
parentParse = loadParse.find_parents_w_child(r'^interface',query)
childParse = loadParse.find_children_w_parents(r'^interface',query)
dictList[query] = dict(zip(parentParse,childParse))
masterDict[count] = dictList
这是配置的摘录。随意复制,粘贴并自己尝试。目的是仅提取查询的行。
interface GigabitEthernet0/1
switchport access vlan 532
switchport mode access
switchport voice vlan 45
switchport port-security maximum 50
switchport port-security
switchport port-security aging time 5
switchport port-security aging type inactivity
auto qos voip cisco-phone
spanning-tree portfast
!
interface GigabitEthernet0/2
switchport access vlan 532
switchport mode access
switchport voice vlan 45
switchport port-security maximum 50
switchport port-security
switchport port-security aging time 5
switchport port-security aging type inactivity
auto qos voip cisco-phone
spanning-tree portfast
!
interface GigabitEthernet0/3
description UPS
switchport access vlan 15
switchport mode access
switchport voice vlan 45
switchport port-security maximum 50
switchport port-security
switchport port-security aging time 5
switchport port-security aging type inactivity
auto qos voip cisco-phone
spanning-tree portfast
!
interface GigabitEthernet0/4
switchport access vlan 532
switchport mode access
switchport voice vlan 45
switchport port-security maximum 50
switchport port-security
switchport port-security aging time 5
switchport port-security aging type inactivity
auto qos voip cisco-phone
spanning-tree portfast
!
interface GigabitEthernet0/5
description Office 207 port 226a Plotter
switchport access vlan 50
switchport mode access
switchport voice vlan 45
switchport port-security maximum 50
switchport port-security
switchport port-security aging time 5
switchport port-security aging type inactivity
speed 10
duplex full
auto qos voip cisco-phone
spanning-tree portfast
!
interface GigabitEthernet0/6
switchport access vlan 532
switchport mode access
switchport voice vlan 45
switchport port-security maximum 50
switchport port-security
switchport port-security aging time 5
switchport port-security aging type inactivity
auto qos voip cisco-phone
spanning-tree portfast
!
interface GigabitEthernet0/7
description Printer Ray Rm 210
switchport access vlan 50
switchport mode access
switchport voice vlan 45
switchport port-security maximum 50
switchport port-security
switchport port-security aging time 5
switchport port-security aging type inactivity
auto qos voip cisco-phone
spanning-tree portfast
!
interface GigabitEthernet0/8
switchport access vlan 532
switchport mode access
switchport voice vlan 45
switchport port-security maximum 50
switchport port-security
switchport port-security aging time 5
switchport port-security aging type inactivity
auto qos voip cisco-phone
spanning-tree portfast
编辑:只是要非常感谢@GhandiFloss和@JoshuaSundance的帮助。 @GhandiFloss的解决方案似乎适用于我上面发布的摘要字典。但是,它不适用于我的完整词典。我正在尝试调整代码,以便做到这一点。再次,朝着正确方向的任何一点将不胜感激! 这是完整的词典:请注意,它可能是从两个几乎相同的配置生成的词典的两倍大。我希望最多可以做4个。
masterDict = {0: {'access': {'interface GigabitEthernet0/1': ' switchport access vlan 532','interface GigabitEthernet0/10': ' switchport access vlan 532','interface GigabitEthernet0/11': ' switchport access vlan 532','interface GigabitEthernet0/12': ' switchport access vlan 532','interface GigabitEthernet0/13': ' switchport access vlan 50','interface GigabitEthernet0/14': ' switchport access vlan 50','interface GigabitEthernet0/15': ' switchport access vlan 532','interface GigabitEthernet0/16': ' switchport access vlan 532','interface GigabitEthernet0/17': ' switchport access vlan 532','interface GigabitEthernet0/18': ' switchport access vlan 50','interface GigabitEthernet0/19': ' switchport access vlan 532','interface GigabitEthernet0/2': ' switchport access vlan 532','interface GigabitEthernet0/20': ' switchport access vlan 50','interface GigabitEthernet0/21': ' switchport access vlan 532','interface GigabitEthernet0/22': ' switchport access vlan 532','interface GigabitEthernet0/23': ' switchport access vlan 532','interface GigabitEthernet0/24': ' switchport access vlan 598','interface GigabitEthernet0/25': ' switchport access vlan 50','interface GigabitEthernet0/26': ' switchport access vlan 64','interface GigabitEthernet0/27': ' switchport access vlan 64','interface GigabitEthernet0/28': ' switchport access vlan 64','interface GigabitEthernet0/29': ' switchport access vlan 50','interface GigabitEthernet0/3': ' switchport access vlan 15','interface GigabitEthernet0/30': ' switchport access vlan 532','interface GigabitEthernet0/31': ' switchport access vlan 50','interface GigabitEthernet0/32': ' switchport access vlan 532','interface GigabitEthernet0/33': ' switchport access vlan 532','interface GigabitEthernet0/34': ' switchport access vlan 50','interface GigabitEthernet0/35': ' switchport access vlan 50','interface GigabitEthernet0/36': ' switchport access vlan 64','interface GigabitEthernet0/37': ' switchport access vlan 64','interface GigabitEthernet0/38': ' switchport access vlan 532','interface GigabitEthernet0/39': ' switchport access vlan 532','interface GigabitEthernet0/4': ' switchport access vlan 532','interface GigabitEthernet0/40': ' switchport access vlan 50','interface GigabitEthernet0/41': ' switchport access vlan 50','interface GigabitEthernet0/42': ' switchport access vlan 50','interface GigabitEthernet0/43': ' switchport access vlan 532','interface GigabitEthernet0/44': ' switchport access vlan 50','interface GigabitEthernet0/45': ' switchport access vlan 50','interface GigabitEthernet0/46': ' switchport access vlan 532','interface GigabitEthernet0/47': ' switchport access vlan 532','interface GigabitEthernet0/48': ' switchport access vlan 532','interface GigabitEthernet0/5': ' switchport access vlan 50','interface GigabitEthernet0/6': ' switchport access vlan 532','interface GigabitEthernet0/7': ' switchport access vlan 50','interface GigabitEthernet0/8': ' switchport access vlan 532','interface GigabitEthernet0/9': ' switchport access vlan 50'},'description': {'interface GigabitEthernet0/13': ' description Printer','interface GigabitEthernet0/14': ' description Printer '
'216','interface GigabitEthernet0/17': ' description bpdu '
'8-19-20 cp','interface GigabitEthernet0/18': ' description FMA 200A '
'Printer','interface GigabitEthernet0/20': ' description Printer '
'209','interface GigabitEthernet0/24': ' description Wireless','interface GigabitEthernet0/25': ' description Printer','interface GigabitEthernet0/26': ' description Camera','interface GigabitEthernet0/27': ' description Camera','interface GigabitEthernet0/28': ' description Camera','interface GigabitEthernet0/3': ' description UPS','interface GigabitEthernet0/35': ' description FMA '
'Printer 204','interface GigabitEthernet0/36': ' description Camera','interface GigabitEthernet0/37': ' description Camera','interface GigabitEthernet0/40': ' description Printer','interface GigabitEthernet0/41': ' description Printer','interface GigabitEthernet0/45': ' description Printer','interface GigabitEthernet0/5': ' description Office 207 '
'port 226a Plotter','interface GigabitEthernet0/51': ' description trunktest','interface GigabitEthernet0/7': ' description Printer Ray '
'Rm 210','interface GigabitEthernet0/9': ' description Printer 213','interface Vlan1000': ' description Management VLAN'},'duplex': {'interface GigabitEthernet0/36': ' duplex half','interface GigabitEthernet0/5': ' duplex full','interface GigabitEthernet0/51': ' duplex full'},'speed': {'interface GigabitEthernet0/36': ' speed 10','interface GigabitEthernet0/5': ' speed 10','interface GigabitEthernet0/51': ' speed 100'},'trunk': {'interface GigabitEthernet0/49': ' switchport mode trunk','interface GigabitEthernet0/50': ' switchport mode trunk','interface GigabitEthernet0/51': ' switchport mode trunk'},'trunkallowed': {'interface GigabitEthernet0/49': ' switchport trunk '
'allowed vlan 50'}},1: {'access': {'interface GigabitEthernet0/1': ' switchport access vlan 532','interface GigabitEthernet0/51': ' switchport mode trunk'}}}
解决方法
这适用于您发布的海量字典。正如我所说的那样,这是一团糟,需要一些工作,但应该会有所帮助。这花了我一段时间,但很烦我,所以想完成它!
def seperate_dicts(dicts):
dict_list = []
keys = list(dicts.keys())
for key in keys:
new_dict = {}
new_dict[key] = dicts[key]
dict_list.append(new_dict)
new_dict = {}
return dict_list
def get_attribs(dict_list):
new_main = {}
key = list(dict_list[0].keys())[0]
new_main['newDict'] = dict_list[0][key]
for i in range(1,len(dict_list)):
other_key = list(dict_list[i].keys())[0]
other_keys = list(dict_list[i][other_key])
for key2 in other_keys:
if key2 not in new_main['newDict']:
new_main['newDict'][key2] = dict_list[i][other_key][key2]
elif isinstance(new_main['newDict'][key2],list):
new_main['newDict'][key2].append(dict_list[i][other_key][key2])
else:
new_main['newDict'][key2] = [
new_main['newDict'][key2],dict_list[i][other_key][key2]]
return new_main
new_master = {}
for i in range(len(masterDict)):
dict_list = seperate_dicts(masterDict[i])
res = get_attribs(dict_list)
new_master[i] = res
print(new_master)
,
(编辑):在查看您的评论并仔细考虑您的需求之后,又会发生什么呢?
# ls will be a list of dicts where each dict represents an interface
ls = []
# testconf is the configuration file from your question
# split it into chunks seperated by the exclamation points
for i in testconf.split('!'):
d = {}
# split each chunk into lines
for l in i.split('\n'):
l = l.strip()
if l != '':
for s in ['interface','switchport mode','description','speed','duplex']:
# if the line starts with the word
if l.startswith(s):
# if the word is already in d
if s in d.keys():
# if it's not a list
if not type(d[s])==list:
d[s] = [d[s],l.replace(s,'').strip()]
else:
# if it is a list
d[s].append(l.replace(s,'').strip())
# if the word is not already in d
else:
d[s] = l.replace(s,'').strip()
# add d to ls
ls.append(d)
access = [d for d in ls if 'access' in list(d.values())]
trunk = [d for d in ls if 'trunk' in list(d.values())]
print(trunk)
print('\n\n\n')
print(access)
输出:
[{'interface': 'GigabitEthernet0/49','switchport mode': 'trunk'},{'interface': 'GigabitEthernet0/50',{'description': 'trunktest','duplex': 'full','interface': 'GigabitEthernet0/51','speed': '100','switchport mode': 'trunk'}]
[{'interface': 'GigabitEthernet0/1','switchport mode': 'access'},{'interface': 'GigabitEthernet0/2',{'description': 'UPS','interface': 'GigabitEthernet0/3',{'interface': 'GigabitEthernet0/4',{'description': 'Office 207 port 226a Plotter','interface': 'GigabitEthernet0/5','speed': '10',{'interface': 'GigabitEthernet0/6',{'description': 'Printer Ray Rm 210','interface': 'GigabitEthernet0/7',{'interface': 'GigabitEthernet0/8',{'description': 'Printer 213','interface': 'GigabitEthernet0/9',{'interface': 'GigabitEthernet0/10',{'interface': 'GigabitEthernet0/11',{'interface': 'GigabitEthernet0/12',{'description': 'Printer','interface': 'GigabitEthernet0/13',{'description': 'Printer 216','interface': 'GigabitEthernet0/14',{'interface': 'GigabitEthernet0/15',{'interface': 'GigabitEthernet0/16',{'description': 'bpdu 8-19-20 cp','interface': 'GigabitEthernet0/17',{'description': 'FMA 200A Printer','interface': 'GigabitEthernet0/18',{'interface': 'GigabitEthernet0/19',{'description': 'Printer 209','interface': 'GigabitEthernet0/20',{'interface': 'GigabitEthernet0/21',{'interface': 'GigabitEthernet0/22',{'interface': 'GigabitEthernet0/23',{'description': 'Wireless','interface': 'GigabitEthernet0/24','interface': 'GigabitEthernet0/25',{'description': 'Camera','interface': 'GigabitEthernet0/26','interface': 'GigabitEthernet0/27','interface': 'GigabitEthernet0/28',{'interface': 'GigabitEthernet0/29',{'interface': 'GigabitEthernet0/30',{'interface': 'GigabitEthernet0/31',{'interface': 'GigabitEthernet0/32',{'interface': 'GigabitEthernet0/33',{'interface': 'GigabitEthernet0/34',{'description': 'FMA Printer 204','interface': 'GigabitEthernet0/35','duplex': 'half','interface': 'GigabitEthernet0/36','interface': 'GigabitEthernet0/37',{'interface': 'GigabitEthernet0/38',{'interface': 'GigabitEthernet0/39','interface': 'GigabitEthernet0/40','interface': 'GigabitEthernet0/41',{'interface': 'GigabitEthernet0/42',{'interface': 'GigabitEthernet0/43',{'interface': 'GigabitEthernet0/44','interface': 'GigabitEthernet0/45',{'interface': 'GigabitEthernet0/46',{'interface': 'GigabitEthernet0/47',{'interface': 'GigabitEthernet0/48','switchport mode': 'access'}]
(旧帖子):我不确定您想要的是什么,因为您想要的最终结果包含语法错误。作为起点,这样的事情怎么样?
def newd(d):
nk = list(list(d.values())[0].keys())[0]
nd = {}
nd['interface'] = nk.replace('interface ','').strip()
for k,v in d.items():
nd[k] = v[nk].replace(k,'').strip()
return nd
{k:newd(v) for k,v in masterDict.items()}
输出:
{0: {'access': 'switchport vlan 532','description': 'Printer','interface': 'GigabitEthernet0/1','trunk': 'switchport mode'},1: {'access': 'switchport vlan 532','interface': 'GigabitEthernet0/2','trunk': 'switchport mode'}}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。