使用重复键在python中创建嵌套字典

时间:2018-09-04 16:38:24

标签: python dictionary

我有以下字典:

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']
}}}}

我如何获得上述结果?

2 个答案:

答案 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开始并向下遍历,直到检测到需要更新为止,这是现有结构与当前字符串的不同之处。 然后解析剩余的字符串并构建要添加的子树,并在到达字符串末尾时进行更新。

您是否有足够的提示来进行编码?