从路径列表创建字典

3

我有一个路径列表:

paths = [
   "root/child1/file1",
   "root/child1/file2",
   "root/child2/file1"
]

我想用Python解析它,生成类似以下的 dict(或者是多个 dictlist):

{
    "text": "root",
    "children": [
        {
            "text": "child1",
            "children": [
                {
                    "text": "file1",
                    "children": []
                },
                {
                    "text": "file2",
                    "children": []
                }
            ]
        },
        {
            "text": "child2",
            "children": [
                {
                    "text": "file2",
                    "children": []
                }
            ]
        }

我试图编写一些递归函数,但没有成功。例如:

def path2dict(path, depth):
    d = {}
    text = path.split('/')[0]
    d['text'] = text
    depth = depth + 1
    d['children'] = [path2dict(p, depth) for p in path.split('/')[depth:]]
    return d

paths = [
   "root/child1/file1",
   "root/child1/file2",
   "root/child2/file1"
]

depth = 0
for path in paths:
    d = path2dict(path, depth)
    print(d)

请分享你的代码。 - balderman
那看起来是儿子Json的工作。 - DirtyBit
2个回答

1

很抱歉没有使用您现有的解决方案,但我有其他方案:

def stage1(paths):
    result = {}
    for path in paths:
        split = path.split('/')
        current = result
        for part in split:
            current.setdefault(part, {})
            current = current[part]
    return result


def stage2(dct):
    return [
        {
            'text': key,
            'children': stage2(value)
        }
        for key, value in dct.items()
    ]


after_stage1 = stage1(paths)

# after_stage1 is
# {
#     'root': {
#         'child1': {
#             'file1': {},
#             'file2': {}
#         },
#         'child2': {
#             'file1': {}
#         }
#     }
# }

after_stage2 = stage2(after_stage1)

# after_stage2 contains exactly what you need

是的,这就是答案,谢谢!你认为有可能创建一步解决方案吗? :) - approximatenumber
我认为是的,而且我认为可能会有不止一种一步解决方案。你自己找到一个解决方案会是一个很好的练习 :) - sanyassh

0
你可以使用 itertools.groupby:
from itertools import groupby
import json
d = ['root/child1/file1', 'root/child1/file2', 'root/child2/file1']
def create_paths(paths): 
  _vals = [[a, [c for _, *c in b]] for a, b in groupby(sorted(paths, key=lambda x:x[0]), key=lambda x:x[0])]
  return [{'text':a, 'children':[] if not b[0] else create_paths(b)} for a, b in _vals]

print(json.dumps(create_paths([i.split('/') for i in d]), indent=4))

输出:

[
   {
    "text": "root",
    "children": [
        {
            "text": "child1",
            "children": [
                {
                    "text": "file1",
                    "children": []
                },
                {
                    "text": "file2",
                    "children": []
                }
            ]
        },
        {
            "text": "child2",
            "children": [
                {
                    "text": "file1",
                    "children": []
                }
            ]
          }
      ]
   }
]

谢谢,是的,它有效,但我需要一些时间来理解这种方式:)) - approximatenumber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接