CSV带ID +父级的JSON树(Python)

时间:2018-12-08 22:12:21

标签: python csv dictionary recursion tree

我遇到了与here相同的问题。有效。但是要完成,我需要一个稍微不同的输出:而不是仅仅

'childs': { ........... }

我想要:

'childs': { placeholder: 'Select', items: { ........... } }

这是当前代码:


    #!/usr/bin/env python
    # -*- coding: utf-8 -*-

    import csv
    import re
    from collections import defaultdict
    from pprint import pprint

    parents = defaultdict(list)

    with open('data.csv',encoding="utf8") as csvfile:
        reader = csv.reader(csvfile, delimiter=',', quotechar='"')
        next(reader)
        count = 1
        for row in reader:
            id_, name, admin_level, parent = row
            parents[parent].append((id_, name))
            count += 1

    def build_tree(d, val):
        return {'lc' + id_: {'val': 'lc' + id_, 'txt': name, 'childs': build_tree(d, id_)} for id_, name in d[val]}
    #pprint(build_tree(parents, ''))
    final = str(build_tree(parents, ''))
    print(final.replace(", 'childs': {}", ""))

使用的CSV是:


    @id,name,admin_level,parent_id
    295480,Portugal,2,
    2897141,Lisboa,3,295480
    3920249,Aveiro,3,295480
    5011694,Leiria,3,295480
    5400843,Loures,4,2897141
    5400844,Mafra,4,2897141

当前输出为:


    {'lc295480': {'childs': {'lc2897141': {'childs': {'lc5400843': {'txt': 'Loures',
                                                                    'val': 'lc5400843'},
                                                      'lc5400844': {'txt': 'Mafra',
                                                                    'val': 'lc5400844'}},
                                           'txt': 'Lisboa',
                                           'val': 'lc2897141'},
                             'lc3920249': {'txt': 'Aveiro',
                                           'val': 'lc3920249'},
                             'lc5011694': {'txt': 'Leiria',
                                           'val': 'lc5011694'}},
                  'txt': 'Portugal',
                  'val': 'lc295480'}}

1 个答案:

答案 0 :(得分:0)

我想这就是你想要的:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# https://stackoverflow.com/questions/53687467/json-tree-from-csv-with-idparent-python
# Just: how to make that "return" give the 'childs': { placeholder: 'Select', items: { ........... } } in that form.

import csv
import re
from collections import defaultdict
from pprint import pprint

def find_branch(node, branch_key):
    for key, item in node.items():
        if key == branch_key:
            return item
        else:
            child_node = find_branch(node[key]['children']['items'], branch_key)
            if child_node:
                return child_node
    return None

tree = {}
with open('data.csv') as csvfile:
    reader = csv.reader(csvfile, delimiter=',', quotechar='"')
    next(reader)
    for row in reader:
        item_id, name, admin_level, parent_id = row
        item_id = 'lc' + item_id
        parent_id = 'lc' + parent_id if parent_id else None
        if parent_id:
            parent_branch = find_branch(tree, parent_id)
            if parent_branch:
                parent_branch['children']['items'][item_id] = dict(name=name, children=dict(placeholder='Select', items={}))
            else:
                print('Branch %s (%s) not found.' % (item_id, name))
                # raise Exception('Branch %s (%s) not found.' % (id, name))
        else:
            tree[item_id] = dict(name=name, children=dict(placeholder='Select', items={}))

pprint(tree)

哪个产生以下输出:

{'lc295480': {'children': {'items': {'lc2897141': {'children': {'items': {'lc5400843': {'children': {'items': {},
                                                                                                 'placeholder': 'Select'},
                                                                                    'name': 'Loures'},
                                                                      'lc5400844': {'children': {'items': {},
                                                                                                 'placeholder': 'Select'},
                                                                                    'name': 'Mafra'}},
                                                            'placeholder': 'Select'},
                                               'name': 'Lisboa'},
                                 'lc3920249': {'children': {'items': {},
                                                            'placeholder': 'Select'},
                                               'name': 'Aveiro'},
                                 'lc5011694': {'children': {'items': {},
                                                            'placeholder': 'Select'},
                                               'name': 'Leiria'}},
                       'placeholder': 'Select'},
          'name': 'Portugal'}}