在Python中,如何从点缀的json文件生成嵌套字典?

问题描述 投票:0回答:2

我有一个类似json的文件:

{
    "a": 0.7615894039735099,
    "a.b": 0.7152317880794702,
    "a.c": 0.026490066225165563
    "a.b.d": 0.0001

     "f": 0.002
     "f.g": 0.00003

     "h.p.q": 0.0004
}

说整个字典称为“根”

我想用这种方式

if "c" in root["a"] and if root["a"]["c"] > 0.0002:
   print("something")

有人可以帮忙吗?非常感谢!

python json dictionary dot
2个回答
0
投票

由于键被散列-字符串键中是否存在点不具有语义含义,并且尝试访问root["a"]["c"]将导致如前所述的TypeError异常。但是,您可以重新构造字典以具有您要查找的嵌套结构。该代码大致如下所示:

root = {
    "a": 0.7615894039735099,
    "a.b": 0.7152317880794702,
    "a.c": 0.026490066225165563,
    "a.b.d": 0.0001,
    "f": 0.002,
    "f.g": 0.00003,
    "h.p.q": 0.0004
}

result = {}
for key, value in root.items():
     if not isinstance(key, str):
         result[key] = value
     is_nested = "." in key
     nesting_clash = any([k.startswith(key) for k in root if k != key])
     if nesting_clash:
         print(f"key {key} has nesting clash")
         continue #raise Exception("There are nesting clashes")
     if not is_nested:
         result[key] = value
     key_parts = key.split(".")
     tmp = result
     for idx, key_part in enumerate(key_parts):
         default_value = {} if idx < len(key_parts) - 1 else value
         tmp[key_part] = tmp.get(key_part, default_value)
         tmp = tmp[key_part]

注意:您必须舍弃发生冲突的键(例如"a""a.b")或为其创建默认行为。在我的示例中,我决定丢弃它们。


0
投票

请看下面的代码段。


def merge(a, b, path=None):
    '''merges b into a'''
    if path is None: path = []
    for key in b:
        if key in a:
            if isinstance(a[key], dict) and isinstance(b[key], dict):
                merge(a[key], b[key], path + [str(key)])
            elif a[key] == b[key]:
                pass # same leaf value
            else:
                raise Exception('Conflict at %s' % '.'.join(path + [str(key)]))
        else:
            a[key] = b[key]
    return a


def convert_dotted_json(dottedJson):
    '''
    parameter
        dottedJson : dict type
    '''
    root = {}

    for key in dottedJson:
        split_key = key.split(".");
        split_key.reverse()
        value = dottedJson [key]
        curr = {split_key[0]: value};
        for ind in range(1, len(split_key)):
            curr = {split_key[ind]:curr}
        root = merge(root, curr)

    return root


test = {
    "a.b.c" : 0.026490066225165563,
    "a.b.d" : 0.0001,
    "f.g": 0.00003,
    "f.h": 0.00003,
    "h.p.q": 0.0004
}

# print(convert_dotted_json(test))

merge function答案中复制Andrew Cook's

© www.soinside.com 2019 - 2024. All rights reserved.