在python中从csv列表创建一个json树

lep*_*ino 3 python csv tree recursion

我正在尝试从python中的一个简单表构建一个json层次结构.

数据如下所示:

id         parent          name
1          10              test-name-1
2          10              test-name-2
3          5               test-name-3
4          none            test-name-4
5          10              test-name-5
6          none            test-name-6
7          1               test-name-7
8          1               test-name-8
9          8               test-name-9
10         4               test-name-10
Run Code Online (Sandbox Code Playgroud)

我正在寻找这样的输出:

{"$4":{"name":"test-name-4","children":{
      "$10":{"name":"test-name-10","children":{
            "$1":{"name":"test-name-1","children":{
                 "$7":{"name":"test-name-7","children":{}},
                 "$8":{"name":"test-name-8","children":{
                      "$9":{"name":"test-name-9","children":{}}}}}},
            "$2":{"name":"test-name-2","children":{}},
            "$5":{"name":"test-name-5","children":{
                 "$3":{"name":"test-name-3","children":{}}}}}}}},
 "$6":{"name":"test-name-6","children":"test-name-6"}}
Run Code Online (Sandbox Code Playgroud)

我不知道会有多少"叶子"或"根",或者来自csv的行的顺序是什么.我的问题是,有没有办法可以从子节点递归地构建字典/列表父母?如何从python中的树的"叶子"片段生成分层树?

谢谢您的帮助!

Emm*_*uel 6

我有一个基于2个循环的解决方案(1个缓存,1个构建),没有JSON编码器,并且可以提供您所需的输出:

>>> import re
>>> from collections import defaultdict
>>> parents = defaultdict(list)
>>> for i, line in enumerate(file_.split('\n')):
    if i != 0 and line.strip():
        id_, parent, name = re.findall(r'[\d\w-]+', line)
        parents[parent].append((id_, name))


>>> parents
defaultdict(<type 'list'>, {'10': [('1', 'test-name-1'), ('2', 'test-name-2'), ('5', 'test-name-5')], 'none': [('4', 'test-name-4'), ('6', 'test-name-6')], '1': [('7', 'test-name-7'), ('8', 'test-name-8')], '5': [('3', 'test-name-3')], '4': [('10', 'test-name-10')], '8': [('9', 'test-name-9')]})
Run Code Online (Sandbox Code Playgroud)

好了,现在我们有了缓存,递归函数很容易构建我们想要的输出:

>>> def build_tree(d, val):
    return {'$' + id_: {'name': name, 'children': build_tree(d, id_)} for id_, name in d[val]}
Run Code Online (Sandbox Code Playgroud)

我们只需要在之前构建的dict上调用它,其值为'none'树根:

>>> from pprint import pprint
>>> pprint(build_tree(parents, 'none'))
{'$4': {'children': {'$10': {'children': {'$1': {'children': {'$7': {'children': {},
                                                                     'name': 'test-name-7'},
                                                              '$8': {'children': {'$9': {'children': {},
                                                                                         'name': 'test-name-9'}},
                                                                     'name': 'test-name-8'}},
                                                 'name': 'test-name-1'},
                                          '$2': {'children': {},
                                                 'name': 'test-name-2'},
                                          '$5': {'children': {'$3': {'children': {},
                                                                     'name': 'test-name-3'}},
                                                 'name': 'test-name-5'}},
                             'name': 'test-name-10'}},
        'name': 'test-name-4'},
 '$6': {'children': {}, 'name': 'test-name-6'}}
>>> 
Run Code Online (Sandbox Code Playgroud)