如何从点分隔的字符串列表中重构JSON?

时间:2016-06-29 08:37:11

标签: python json dictionary nested nested-loops

有人会认为这样做很容易。我发誓,只是......我似乎无法弄明白。我该如何改造:

terrible_way_to_describe_nested_json=['a.b.c','a.b.d','a.e','a.f','g.h']

进入

{
    "a": {
        "b": {
            "c": None,
            "d": None
        },
        "e": None,
        "f": None
    },
    "g": {
        "h": None
    }
}

如果您考虑解构JSON加载的'a.b.c' 路径,那么我有大约200个这些未排序的路径(转换应该无论顺序如何都可以工作),最多可达8个点所有人都渴望成为他们原有结构的一部分。我尝试使用递归来解决这个问题,使用pandas来对内部的叶子节点进行排序(荒谬吗?),疯狂的列表列表知道,甚至是autovivification

毁灭和绝望的领域

这是我编写/放弃的6个部分实现之一。它甚至在边缘节点之前剥离嵌套键的层然后我放松了我的思想。我几乎建议忽略它。

def dot_to_json(dotted_paths):
    scope_map=[line.split('.') for line in dotted_paths] #Convert dots list to strings
    # Sort and group list of strings according to length of list. longest group is last
    b=[]
    for index in range(max([len(x) for x in scope_map])+1):
        a=[]
        for item in scope_map:
            if len(item)==index:
                a.append(item)
        b.append(a)
    sorted_nest=[x for x in b if x] # finally group according to list length
    #Point AA
    # group string list 'prefix' with key:value
    child_path=[]
    for item in sorted_nest[-1]:
        child_path.append([item[:-1],{item[-1]:None}])
    # peel back a layer
    new_child_path=[]
    for scope in scope_map[-2]:
        value=None # set value to None if fringe node
        for index, path in enumerate(child_path):
            if path[0]==scope: # else, save key + value as a value to the new prefix key
                value=path[1]
                child_path.pop(index) # 'move' this path off child_path list
        new_child_path.append([scope[:-1],{scope[-1]:value}])
    new_child_path+=child_path
    #Point BB...
    #Loop in some intelligent way between Point AA and Point BB
    return new_child_path
#%%
dotted_json=['a.b.c','a.b.d','a.e','a.f','g.h']

scope_map=dot_to_json(dotted_json)

2 个答案:

答案 0 :(得分:3)

你走了:

In [5]: terrible_way_to_describe_nested_json=['a.b.c','a.b.d','a.e','a.f','g.h']

In [6]: terrible_way_to_describe_nested_json = [s.split('.') for s in terrible_way_to_describe_nested_json]

In [7]: data = {}

In [8]: for path in terrible_way_to_describe_nested_json:
   ....:     curr = data
   ....:     for i, node in enumerate(path):
   ....:         if i == len(path) - 1:
   ....:             curr[node] = None
   ....:         else:
   ....:             curr = curr.setdefault(node,{})
   ....:             

In [9]: data
Out[9]: {'a': {'b': {'c': None, 'd': None}, 'e': None, 'f': None}, 'g': {'h': None}}

现在使用json模块进行相当打印会产生:

{
    "a": {
        "f": null,
        "b": {
            "d": null,
            "c": null
        },
        "e": null
    },
    "g": {
        "h": null
    }
}

这两个应该是等同的,但是不按顺序打印,或者至少打印失序。

答案 1 :(得分:0)

试用dpath模块,它可以用来轻松添加/过滤/搜索词典。通过用'/'字符替换点,您可以创建所需的dict