python - 无法使用唯一的第一个键确定性地更新嵌套字典

标签 python dictionary nested python-2.6

我正在尝试创建字典来镜像类中的网络硬件。我嵌套了几个对象属性,以便于管理以后的代码:

    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

我已经尝试了我能想到的一切。我遇到了错误还是错过了一些基本的东西?

最佳答案

您在外部词典中多次引用相同的内部词典。这就是为什么您会看到您所做的修改的最新版本反射(reflect)在多个位置。

正如 J.F. Sebastian 所评论的,当您将“原型(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的一处地方,但这可能不值得,因为你稍后编辑代码时很容易犯错误并返回到原来的问题。

关于python - 无法使用唯一的第一个键确定性地更新嵌套字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31417570/

相关文章:

python - matplotlib 的 detrend_linear 显示去趋势 sin(t) 的偏差

Python re.findall 从文件

python - 如何将此字典列表转换为 csv 文件?

python - 将文件更改为列表更改为字典

Python嵌套if-else只执行else

templates - 嵌套模板,查找父级

python - 访问在字典中找到的 'Tkinter' 按钮

python - 检查列表中是否存在具有特定值的字典

c# - 如何用数组值初始化字典?

javascript - 带有反应路由器 v4/v5 的嵌套路由