如何将json_key_dots与json_key_brackets进行比较?

时间:2017-09-11 18:00:03

标签: python json brackets

我有两个要比较的文件,并插入缺少key_value的第二个文件或使用新值更新现有密钥。 对我来说问题是第一个文件有点分隔键:

{"a.b.c":0}

第二个文件如下:

{"a":{"b":{"c":0}}}

2 个答案:

答案 0 :(得分:0)

我最近不得不处理类似的事情。这就是我想出的:

def to_flat_dict(d, delim='.'):
    """TLDR;
    While there are entries in the dictionary that have a dict as a value:
        pop them at the outer level and create a delimitted path as a key, eg:
            {'a': {'b': {'c': 0}}} -> {'a.b': {'c': 0}}
            # by same process
            {'a.b': {'c': 0}} -> {'a.b.c': 0}
    """
    flat = dict(d)   # work on a copy
    incomplete = list(flat)  
    while(incomplete):
        k = incomplete.pop()
        if isinstance(flat[k], dict):
            val = flat.pop(k)
            for subk, subv in val.items():
                new_key = delim.join((k, subk))
                flat[new_key] = subv
                incomplete.append(new_key)
    return flat


def to_nested_dict(d, delim='.'):
    """TLDR;

    flat: {"a.b.c":0}
    # pop 'a.b.c' and value 0 and break key into parts
    parts:  ['a','b','c']:

    # process 'a'
    flat <- {'a':dict()} 
    # process 'b'
    flat <- {'a': {'b': dict()}} 
    # process 'c' @ tmp[parts[-1]] = val
    flat <- {'a': {'b': {'c': 0}}} 

    """
    flat = dict(d) # work on a copy
    keys = list(d) # we copy the keys since we are modifying the dict in place
    for key in keys:
        # Basic idea: for all keys that contain the delim
        if delim in key:
            val = flat.pop(key)
            # get the parts (a.b.c -> [a, b, c])
            parts = key.split(delim)
            # we start with the outer dict, but as we process parts of the key
            level = flat # we assign level to the newly created deeper dicts
            for part in parts[:-1]:
                if part not in level:   # if the part isn't a key at this depth
                    level[part] = dict() # create a new dict to fill
                level = level[part]      # and work on the next deeper level
            level[parts[-1]] = val # when we get to the "leaf" set it as val
    return flat

您可以致电:

获取所需的嵌套字典
to_nested_dict({'a.b.c':0})

您可以使用 to_flat_dict

将其反转
to_flat_dict(to_nested_dict({'a.b.c':0})) # back to {'a.b.c':0}

您的里程可能会有所不同!

答案 1 :(得分:0)

我编写的代码对我有用,但我讨厌它,尤其是ff_function。 我认为应该使用递归函数来完成 - 不知道如何:(

>>> def ff(k, d, i, v):
...   if i == len(k)-1:
...     last_value = v 
...   else:
...     last_value = {}
...   if i == 0:
...     d[k[0]] = last_value
...   elif i == 1:
...     d[k[0]][k[1]] = last_value
...   elif i == 2:
...     d[k[0]][k[1]][k[2]] = last_value
...   elif i == 3:
...     d[k[0]][k[1]][k[2]][k[3]] = last_value
...   elif i == 4:
...     d[k[0]][k[1]][k[2]][k[3]][k[4]] = last_value
...   elif i == 5:
...     d[k[0]][k[1]][k[2]][k[3]][k[4]][k[5]] = last_value
...   return d
... 
>>> 
>>> 
>>> def f(k, v):
...   td = {}
...   keys = k.split('.')
...   for i in range(len(keys)):
...     td = ff(keys, td, i, v)
...   return td
... 
>>> 
>>> f('a.b.c.d', ['some', 'values', 'here'])
{'a': {'b': {'c': {'d': ['some', 'values', 'here']}}}}
>>> f('a', 0)
{'a': 0}