Create a json tree from csv list in python

后端 未结 3 1299
一生所求
一生所求 2020-12-19 20:05

I\'m trying to build a json hierarchy from a simple table in python.

The data comes in looking like the following:

id         parent          name
1          


        
3条回答
  •  北海茫月
    2020-12-19 20:56

    The answer given did not work for me in python 3.6 because Dict.Dict has been deprecated. So I made some changes to make it work and generalized it a little by letting user specify columns for child_id, parent_id and child name via command line. Please see below (I am just learning and am sure this could be improved, but it works for my purposes).

    """ Converts a CSV file with Parent/Child Hierarchy to a hierarchical JSON file for front-end processing (javascript/DS)
    
    USAGE: csv2json.py  a b c  (column nrs of a=child_id, b=parent-id, c=name(of child))
    
    ROOT of hierarchy should contain child_id and parent_id = 'none' or blank.  name must exist """
    
    import sys
    import json
    import csv
    #import UserDict
    from collections import UserDict
    
    class Node(object):
        def __init__(self, child_id, parent_id, name):
            self.child_id = child_id
            self.parent_id = parent_id
            self.children = []
            self.name = name
    
    class NodeDict(UserDict):
        def addNodes(self, nodes):
            """ Add every node as a child to its parent_id by doing two passes."""
            for i in (1, 2):
                for node in nodes:
                    self.data[node.child_id] = node
                    if node.parent_id in self.data.keys():
                        if (node.parent_id != "none" or node.parent_id != "") and node not in self.data[node.parent_id].children:
                            self.data[node.parent_id].children.append(node)
    
    class NodeJSONEncoder(json.JSONEncoder):
        def default(self, node):
            if type(node) == Node:
                return {"name":node.name, "children":node.children}
                raise TypeError("{} is not an instance of Node".format(node))
    
    if __name__ == "__main__":
        nodes = []
    
        with open(sys.argv[1], 'r') as f:
            reader = csv.reader(f)
            for row in reader:
                if not row[int(sys.argv[4])] : #skip if no name/label exists
                    continue
                child_id, parent_id, name = row[int(sys.argv[2])] , row[int(sys.argv[3])] , row[int(sys.argv[4])]
    
                nodes.append(Node(child_id, parent_id, name))
    
        nodeDict = NodeDict()
        nodeDict.addNodes(nodes)
    
        rootNodes = [node for child_id, node in nodeDict.items()
                     if (node.parent_id == "none" or node.parent_id == "")]
        for rootNode in rootNodes:
            print(NodeJSONEncoder().encode(rootNode))
    

提交回复
热议问题