Python 中的嵌套字典:分配键,但保留子结构
Nested dictionary in Python: Assigning keys, BUT keeping sub structure
我正在使用 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'
有没有办法为嵌套键分配一个新名称,但保留以下子键和值的结构,就像我的例子一样?
我希望有人能帮助我。非常感谢和最诚挚的问候
您可以简单地将值转移到新键,然后删除旧键。例如:
dict_var['file']['1'] = dict_var['file']['index']
del dict_var['file']['index']
您可以使用嵌套 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,我发现了另外两个优雅的解决方案:
- 来自用户 Vincent
使用 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.
>>> 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: {}}}}}}
我正在使用 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'
有没有办法为嵌套键分配一个新名称,但保留以下子键和值的结构,就像我的例子一样? 我希望有人能帮助我。非常感谢和最诚挚的问候
您可以简单地将值转移到新键,然后删除旧键。例如:
dict_var['file']['1'] = dict_var['file']['index']
del dict_var['file']['index']
您可以使用嵌套 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,我发现了另外两个优雅的解决方案:
- 来自用户 Vincent
使用 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.
>>> 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: {}}}}}}