2016-09-29 44 views
1

我使用Python 3.5,我有一个问题分配值的字典键。我的字典的结构是这样的:在Python中嵌套的字典:分配键,但保持子结构

dict_var = {'file': 
       {'index': 
        {'flag': 
         {'flag_key': 'False'}, 
        'attr': 
         {'attr_key': 'attr_val'}, 
        'path': 
         {'path_key': 'path_val'}, 
        } 
       } 
      } 

我得到KeyError异常:1,如果我改变了套叠的键'index'这样的:

dict_var['file']['1']['flag'] = 'some value' 
dict_var['file']['2']['flag'] = 'some value' 
dict_var['file']['3']['flag'] = 'some value' 
dict_var['file']['4']['flag'] = 'some value' 

,或者如果我试图改变嵌套关键'flag'

dict_var['file']['index']['flag_2']['flag_key'] = 'some value' 

是否有分配一个新名称为嵌套关键,但保持下面的子项和值的结构方式,就像在我的例子吗? 我希望有人能帮助我。非常感谢,并提前问候

回答

3

您可以使用嵌套defaultdict,像这样:

from collections import defaultdict 

ndefaultdict = lambda:defaultdict(ndefaultdict) 

dict_var = ndefaultdict() 
dict_var['file']['1']['flag'] = 'some value' 
dict_var['file']['2']['flag'] = 'some value' 
dict_var['file']['3']['flag'] = 'some value' 
dict_var['file']['4']['flag'] = 'some value' 

然后,您可以编写一个简单的循环,从原来的字典传递信息到嵌套的字典。 一个例子的解决方案:

from collections import defaultdict 

def ndefaultdict(orig_dict): 
    l = lambda: defaultdict(l) 
    out = l() 

    def n_helper(orig_dict, nesteddict): 
     for k, v in orig_dict.items(): 
      if isinstance(v, dict): 
       n_helper(v, nesteddict[k]) 
      else: 
       nesteddict[k] = v 
     return nesteddict 

    return n_helper(orig_dict, out) 

# dict_var is the original dictionary from the OP. 
new_dict = n_defaultdict(dict_var) 
new_dict['foo']['bar']['baz'] = 'It works!!' 

print(new_dict['file']['index']['attr']['attr_key']) # attr_val 

编辑:

看着this SO thread,我发现了另外两个优雅的解决方案:

  1. 从用户文森特

与defaultdict简短的解决方案

from collections import defaultdict 

def superdict(arg=()): 
    update = lambda obj, arg: obj.update(arg) or obj 
    return update(defaultdict(superdict), arg) 

>>> d = {"a":1} 
>>> sd = superdict(d) 
>>> sd["b"]["c"] = 2 
  • 从用户DVD Avins
  • 使用定制NestedDict类。

    >>> class NestedDict(dict): 
    ...  def __getitem__(self, key): 
    ...   if key in self: return self.get(key) 
    ...   return self.setdefault(key, NestedDict()) 
    
    
    >>> eggs = NestedDict() 
    >>> eggs[1][2][3][4][5] 
    {} 
    >>> eggs 
    {1: {2: {3: {4: {5: {}}}}}} 
    
    +0

    谢谢!我认为'class NestedDict(dict)'是我正在寻找的东西。我会尽力与它合作。 – saitam

    1

    您可以简单地将值转移到新的密钥,然后删除旧的。例如:

    dict_var['file']['1'] = dict_var['file']['index'] 
    del dict_var['file']['index']