我有以下字典:
d = {
'results.household.land_tenure_access_restitution.has_land_allocated_relation': ['false', 'true'],
"results.household.land_tenure_access_restitution.is_status_of_claim_required": ["false", "true"]
}
我需要创建以下内容:
d2 = {
'results': {
'household': {
'land_tenure_access_restitution': {
'is_status_of_claim_required': ['false', 'true'],
'has_land_allocated_relation': ['false', 'true']
}
}
}
}
我写了以下代码:
f = {}
g = {}
for key, value in d.iteritems():
print f
for n, k in enumerate(reversed(key.split('.'))):
if n == 0:
f = {k: d[key]}
else:
f = {k: f}
g.update(f)
但是,由于上级键不是唯一的,因此词典会被最新的键值覆盖。我得到以下输出:
{
'results': {
'household': {'land_tenure_access_restitution': {
'has_land_allocated_relation': ['false', 'true']
}}}}
我如何获得上述结果?
答案 0 :(得分:2)
您可以递归合并字典:
from functools import reduce
import collections
d = {
'results.household.land_tenure_access_restitution.has_land_allocated_relation': ['false', 'true'],
"results.household.land_tenure_access_restitution.is_status_of_claim_required": ["false", "true"]
}
def dict_merge(dct, merge_dct):
for key, value in merge_dct.items():
if key in dct and isinstance(dct[key], dict) and isinstance(merge_dct[key], collections.Mapping):
dict_merge(dct[key], merge_dct[key])
else:
dct[key] = merge_dct[key]
result = {}
for k, v in d.items():
elements = [v] + list(reversed(k.split('.')))
nested = reduce(lambda x, y: {y: x}, elements)
dict_merge(result, nested)
print(result)
输出
{'results': {'household': {'land_tenure_access_restitution': {'has_land_allocated_relation': ['false', 'true'], 'is_status_of_claim_required': ['false', 'true']}}}}
函数dict_merge
递归合并两个字典,这些行:
elements = [v] + list(reversed(k.split('.')))
nested = reduce(lambda x, y: {y: x}, elements)
为原始词典的每个键创建一个嵌套词典。
答案 1 :(得分:1)
您更新的过程太迟了:请注意,只有在遍历整个字符串并且返回到dict的最高级别时,更新才可能发生。只要根匹配,就替换整个树。
您需要从树的根results
开始并向下遍历,直到检测到需要更新为止,这是现有结构与当前字符串的不同之处。 然后解析剩余的字符串并构建要添加的子树,并在到达字符串末尾时进行更新。
您是否有足够的提示来进行编码?