我正在使用Python 3.5,我在向字典键分配值时遇到问题。我的字典结构如下:
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'
有没有办法为嵌套键分配新名称,但保留以下子键和值的结构,就像在我的示例中一样? 我希望有人可以帮助我。非常感谢和提前致以最好的问候
答案 0 :(得分: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,我找到了另外两个优雅的解决方案:
使用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
使用自定义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: {}}}}}}
答案 1 :(得分:1)
您可以简单地将值传输到新密钥,然后删除旧密钥。例如:
dict_var['file']['1'] = dict_var['file']['index']
del dict_var['file']['index']