我有以下字典:
my_dict = {'key1': {'key2': {'foo': 'bar'} } }
我想在key1-> key2-> key3上添加一个条目,其值为' blah'得到以下特性:
my_dict = {'key1': {'key2': {'foo': 'bar', 'key3': 'blah'} } }
我正在寻找一个独立于密钥数量的通用解决方案,即key1-> key2-> key3-> key4-> key5应该也能正常工作,即使key3上的键位于向下也是如此不存在。所以我得到了:
my_dict = {'key1': {'key2': {'foo': 'bar', 'key3': {'key4': {'key5': 'blah'} } } } }
提前致谢。
答案 0 :(得分:12)
您可以使用reduce()
function遍历一系列嵌套词典:
def get_nested(d, path):
return reduce(dict.__getitem__, path, d)
演示:
>>> def get_nested(d, path):
... return reduce(dict.__getitem__, path, d)
...
>>> my_dict = {'key1': {'key2': {'foo': 'bar', 'key3': {'key4': {'key5': 'blah'}}}}}
>>> get_nested(my_dict, ('key1', 'key2', 'key3', 'key4', 'key5'))
'blah'
当密钥不存在时,此版本抛出异常:
>>> get_nested(my_dict, ('key1', 'nonesuch'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in get_nested
KeyError: 'nonesuch'
但您可以将dict.__getitem__
替换为lambda d, k: d.setdefault(k, {})
,以使其创建空字典:
def get_nested_default(d, path):
return reduce(lambda d, k: d.setdefault(k, {}), path, d)
演示:
>>> def get_nested_default(d, path):
... return reduce(lambda d, k: d.setdefault(k, {}), path, d)
...
>>> get_nested_default(my_dict, ('key1', 'nonesuch'))
{}
>>> my_dict
{'key1': {'key2': {'key3': {'key4': {'key5': 'blah'}}, 'foo': 'bar'}, 'nonesuch': {}}}
要设置给定路径的值,遍历除最后一个键之外的所有键,然后在常规字典赋值中使用最终键:
def set_nested(d, path, value):
get_nested_default(d, path[:-1])[path[-1]] = value
这使用get_nested_default()
函数根据需要添加空字典:
>>> def set_nested(d, path, value):
... get_nested_default(d, path[:-1])[path[-1]] = value
...
>>> my_dict = {'key1': {'key2': {'foo': 'bar'}}}
>>> set_nested(my_dict, ('key1', 'key2', 'key3', 'key4', 'key5'), 'blah')
>>> my_dict
{'key1': {'key2': {'key3': {'key4': {'key5': 'blah'}}, 'foo': 'bar'}}}
答案 1 :(得分:1)
Martijn Pieters的另一个很好的答案是使用嵌套的defaultdict
,而不是常规词典:
from collections import defaultdict
nested = lambda: defaultdict(nested) # nested dictionary factory
my_dict = nested()
您可以使用常规嵌套字典访问语义来设置值,并且将创建空字典以根据需要填充中间级别:
my_dict["key1"]["key2"]["key3"] = "blah"
当然,当您编写代码来设置值时,这需要事先知道密钥的数量。如果您希望能够处理可变长度的键列表而不是固定的数字,那么您需要使用函数来为您进行获取和设置,例如在Martijn的答案中。