根据路径列表做出命令

时间:2019-02-21 11:08:53

标签: python recursion

我有路径列表:

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

我想用python将其解析为dict(或list中的dict),如下所示:

{
    "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)

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:-1)

您可以使用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": []
                }
            ]
          }
      ]
   }
]