无法使用唯一的第一个键确定性地更新嵌套字典
Can't deterministically update nested dictionaries with unique first key
我正在尝试创建字典以在 Class 中镜像网络硬件。我嵌套了几个对象属性,以便于管理以后的代码:
self.hw_profile = defaultdict(dict)
self.a1k2x_dict = defaultdict(dict)
self.a1k4_dict = defaultdict(dict)
self.a1k6_dict = defaultdict(dict)
self.spa_none = {}
int_map = {'local_int':"", 'local_pc':"", 'opp_dev_desc':"", 'opp_dev_match':"", 'opp_int':""}
self.spa_6x1g = {'spa_name':"6XGE-BUILT-IN",
'int_type' : 'GigabitEthernet',
'int_quant' : 6,
'int_map' : int_map
}
self.spa_1x10g = {'spa_name' : 'SPA-1X10GE-L-V2',
'int_type' : 'TenGigabitEthernet',
'int_quant' : 1,
'int_map' : int_map
}
self.spa_5x1g = {'spa_name' : "SPA-5X1GE-V2",
'int_type' : 'GigabitEthernet',
'int_quant' : 5,
'int_map' : int_map
}
self.a1k6_dict = {'slot0':
{'spa0': self.spa_1x10g,
'spa1': self.spa_none,
'spa2': self.spa_none,
'spa3': self.spa_5x1g},
'slot1':
{'spa0': self.spa_1x10g,
'spa1': self.spa_1x10g,
'spa2': self.spa_none,
'spa3': self.spa_none},
'slot2':
{'spa0': self.spa_1x10g,
'spa1': self.spa_1x10g,
'spa2': self.spa_none,
'spa3': self.spa_none}
}
self.a1k2x_dict = {'slot0':
{'spa0': self.spa_6x1g,
'spa1': self.spa_5x1g,
'spa2': self.spa_none,
'spa3': self.spa_none},
}
现在我想使用这些抽象字典并用特定值填充它们。我尝试使用 .get
/.update
或简单地使用 self.hw_profile['slot0']['spa1'] = x
等设置新值
elif self.hw_name == "cisco-asr-1006":
self.hw_profile = self.a1k6_dict
temp_dict1 = {'local_int' : "0/0/0" , 'local_pc':"", 'opp_dev_desc' : "blah1", 'opp_dev_match' :
self.re_core1_match, 'opp_int':"" }
self.hw_profile.get('slot0', {}).get('spa0', {}).get('int_map', {}).update(temp_dict1)
temp_dict2 = {'local_int' : "1/0/0" , 'local_pc':"", 'opp_dev_desc' : "blah2", 'opp_dev_match' :
self.re_core2_match, 'opp_int':"" }
self.hw_profile.get('slot1', {}).get('spa0', {}).get('int_map', {}).update(temp_dict2)
temp_dict3 = {'local_int' : "2/0/0" , 'local_pc':"", 'opp_dev_desc' : "blah", 'opp_dev_match' :
self.re_alg_match, 'opp_int':"" }
self.hw_profile.get('slot2', {}).get('spa0', {}).get('int_map', {}).update(temp_dict3)
我遇到的问题是,无论我做什么,字典中的第一个键似乎都被忽略了,树下的所有分支都写入了最后一个值,如此打印输出所示词典:
[slot1]
[spa2]
[spa3]
[spa0]
spa_name = SPA-1X10GE-L-V2
[int_map]
opp_dev_desc = opposing ALG
local_int = 2/0/0
local_pc =
opp_dev_match = <_sre.SRE_Pattern object at 0x7f647551b870>
opp_int =
int_quant = 1
int_type = TenGigabitEthernet
[spa1]
spa_name = SPA-1X10GE-L-V2
[int_map]
opp_dev_desc = blah
local_int = 2/0/0
local_pc =
opp_dev_match = <_sre.SRE_Pattern object at 0x7f647551b870>
opp_int =
int_quant = 1
int_type = TenGigabitEthernet
[slot0]
[spa2]
[spa3]
spa_name = SPA-5X1GE-V2
[int_map]
opp_dev_desc = blah
local_int = 2/0/0
local_pc =
opp_dev_match = <_sre.SRE_Pattern object at 0x7f647551b870>
opp_int =
int_quant = 5
int_type = GigabitEthernet
[spa0]
spa_name = SPA-1X10GE-L-V2
[int_map]
opp_dev_desc = opposing ALG
local_int = 2/0/0
local_pc =
opp_dev_match = <_sre.SRE_Pattern object at 0x7f647551b870>
opp_int =
int_quant = 1
int_type = TenGigabitEthernet
[spa1]
[slot2]
[spa2]
[spa3]
[spa0]
spa_name = SPA-1X10GE-L-V2
[int_map]
opp_dev_desc = blah
local_int = 2/0/0
local_pc =
opp_dev_match = <_sre.SRE_Pattern object at 0x7f647551b870>
opp_int =
int_quant = 1
int_type = TenGigabitEthernet
[spa1]
spa_name = SPA-1X10GE-L-V2
[int_map]
opp_dev_desc = opposing ALG
local_int = 2/0/0
local_pc =
opp_dev_match = <_sre.SRE_Pattern object at 0x7f647551b870>
opp_int =
int_quant = 1
int_type = TenGigabitEthernet
我已经尝试了这里能想到的一切。我是遇到了错误还是遗漏了一些基本知识?
您在外部词典中多次引用相同的内部词典。这就是为什么您会在多个地方看到您所做修改的最新版本。
作为J.F。塞巴斯蒂安评论说,当您将 "prototype" 词典添加到外部词典时(例如 int_map.copy()
或 copy.deepcopy(spa_1x10g)
),您可以通过复制它们来解决这个问题。这样可以确保每个引用相同结构字典的位置都有一个单独的实例,因此它们可以独立修改。
这是一个更简单的示例,显示了您遇到的相同问题:
inner_dict = {0: 0}
outer_dict = {1: inner_dict, 2: inner_dict}
outer_dict[1][0] = 1
outer_dict[2][0] = 2
print(outer_dict) # prints {1: {0: 2}, 2: {0: 2}}
print(outer_dict[1] is outer_dict[2] is inner_dict) # prints True, they're the same dict
这是 outer_dict
定义的固定版本,没有这个问题:
outer_dict = {1: inner_dict.copy(), 2: inner_dict.copy()}
在此版本中,outer_dict[1]
和 outer_dict[2]
不再引用同一个内部字典,因此您可以独立编辑它们的值。
我想你可以不用完全复制你引用的一个地方 inner_dict
,但这可能不值得,因为你在稍后编辑代码时很容易出错并返回到原始代码问题。
我正在尝试创建字典以在 Class 中镜像网络硬件。我嵌套了几个对象属性,以便于管理以后的代码:
self.hw_profile = defaultdict(dict)
self.a1k2x_dict = defaultdict(dict)
self.a1k4_dict = defaultdict(dict)
self.a1k6_dict = defaultdict(dict)
self.spa_none = {}
int_map = {'local_int':"", 'local_pc':"", 'opp_dev_desc':"", 'opp_dev_match':"", 'opp_int':""}
self.spa_6x1g = {'spa_name':"6XGE-BUILT-IN",
'int_type' : 'GigabitEthernet',
'int_quant' : 6,
'int_map' : int_map
}
self.spa_1x10g = {'spa_name' : 'SPA-1X10GE-L-V2',
'int_type' : 'TenGigabitEthernet',
'int_quant' : 1,
'int_map' : int_map
}
self.spa_5x1g = {'spa_name' : "SPA-5X1GE-V2",
'int_type' : 'GigabitEthernet',
'int_quant' : 5,
'int_map' : int_map
}
self.a1k6_dict = {'slot0':
{'spa0': self.spa_1x10g,
'spa1': self.spa_none,
'spa2': self.spa_none,
'spa3': self.spa_5x1g},
'slot1':
{'spa0': self.spa_1x10g,
'spa1': self.spa_1x10g,
'spa2': self.spa_none,
'spa3': self.spa_none},
'slot2':
{'spa0': self.spa_1x10g,
'spa1': self.spa_1x10g,
'spa2': self.spa_none,
'spa3': self.spa_none}
}
self.a1k2x_dict = {'slot0':
{'spa0': self.spa_6x1g,
'spa1': self.spa_5x1g,
'spa2': self.spa_none,
'spa3': self.spa_none},
}
现在我想使用这些抽象字典并用特定值填充它们。我尝试使用 .get
/.update
或简单地使用 self.hw_profile['slot0']['spa1'] = x
等设置新值
elif self.hw_name == "cisco-asr-1006":
self.hw_profile = self.a1k6_dict
temp_dict1 = {'local_int' : "0/0/0" , 'local_pc':"", 'opp_dev_desc' : "blah1", 'opp_dev_match' :
self.re_core1_match, 'opp_int':"" }
self.hw_profile.get('slot0', {}).get('spa0', {}).get('int_map', {}).update(temp_dict1)
temp_dict2 = {'local_int' : "1/0/0" , 'local_pc':"", 'opp_dev_desc' : "blah2", 'opp_dev_match' :
self.re_core2_match, 'opp_int':"" }
self.hw_profile.get('slot1', {}).get('spa0', {}).get('int_map', {}).update(temp_dict2)
temp_dict3 = {'local_int' : "2/0/0" , 'local_pc':"", 'opp_dev_desc' : "blah", 'opp_dev_match' :
self.re_alg_match, 'opp_int':"" }
self.hw_profile.get('slot2', {}).get('spa0', {}).get('int_map', {}).update(temp_dict3)
我遇到的问题是,无论我做什么,字典中的第一个键似乎都被忽略了,树下的所有分支都写入了最后一个值,如此打印输出所示词典:
[slot1]
[spa2]
[spa3]
[spa0]
spa_name = SPA-1X10GE-L-V2
[int_map]
opp_dev_desc = opposing ALG
local_int = 2/0/0
local_pc =
opp_dev_match = <_sre.SRE_Pattern object at 0x7f647551b870>
opp_int =
int_quant = 1
int_type = TenGigabitEthernet
[spa1]
spa_name = SPA-1X10GE-L-V2
[int_map]
opp_dev_desc = blah
local_int = 2/0/0
local_pc =
opp_dev_match = <_sre.SRE_Pattern object at 0x7f647551b870>
opp_int =
int_quant = 1
int_type = TenGigabitEthernet
[slot0]
[spa2]
[spa3]
spa_name = SPA-5X1GE-V2
[int_map]
opp_dev_desc = blah
local_int = 2/0/0
local_pc =
opp_dev_match = <_sre.SRE_Pattern object at 0x7f647551b870>
opp_int =
int_quant = 5
int_type = GigabitEthernet
[spa0]
spa_name = SPA-1X10GE-L-V2
[int_map]
opp_dev_desc = opposing ALG
local_int = 2/0/0
local_pc =
opp_dev_match = <_sre.SRE_Pattern object at 0x7f647551b870>
opp_int =
int_quant = 1
int_type = TenGigabitEthernet
[spa1]
[slot2]
[spa2]
[spa3]
[spa0]
spa_name = SPA-1X10GE-L-V2
[int_map]
opp_dev_desc = blah
local_int = 2/0/0
local_pc =
opp_dev_match = <_sre.SRE_Pattern object at 0x7f647551b870>
opp_int =
int_quant = 1
int_type = TenGigabitEthernet
[spa1]
spa_name = SPA-1X10GE-L-V2
[int_map]
opp_dev_desc = opposing ALG
local_int = 2/0/0
local_pc =
opp_dev_match = <_sre.SRE_Pattern object at 0x7f647551b870>
opp_int =
int_quant = 1
int_type = TenGigabitEthernet
我已经尝试了这里能想到的一切。我是遇到了错误还是遗漏了一些基本知识?
您在外部词典中多次引用相同的内部词典。这就是为什么您会在多个地方看到您所做修改的最新版本。
作为J.F。塞巴斯蒂安评论说,当您将 "prototype" 词典添加到外部词典时(例如 int_map.copy()
或 copy.deepcopy(spa_1x10g)
),您可以通过复制它们来解决这个问题。这样可以确保每个引用相同结构字典的位置都有一个单独的实例,因此它们可以独立修改。
这是一个更简单的示例,显示了您遇到的相同问题:
inner_dict = {0: 0}
outer_dict = {1: inner_dict, 2: inner_dict}
outer_dict[1][0] = 1
outer_dict[2][0] = 2
print(outer_dict) # prints {1: {0: 2}, 2: {0: 2}}
print(outer_dict[1] is outer_dict[2] is inner_dict) # prints True, they're the same dict
这是 outer_dict
定义的固定版本,没有这个问题:
outer_dict = {1: inner_dict.copy(), 2: inner_dict.copy()}
在此版本中,outer_dict[1]
和 outer_dict[2]
不再引用同一个内部字典,因此您可以独立编辑它们的值。
我想你可以不用完全复制你引用的一个地方 inner_dict
,但这可能不值得,因为你在稍后编辑代码时很容易出错并返回到原始代码问题。