从python中的csv list创建一个json树 [英] Create a json tree from csv list in python

查看:296
本文介绍了从python中的csv list创建一个json树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我试图从一个简单的表中构建一个json层次结构。数据看起来像下面这样:

  id父名称
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无test-name-6
7 1 test-name-7
8 1 test-name-8
9 8 test-name-9
10 4 test-name-10

我正在寻找这样的输出:

  {$ 4:{ 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-2,children:{}},
$ 5:{name: test-name-5,children:{
$ 3:{name:test-name-3,children:{}}}}}}},
$ 6:{name:test-name-6,children:test-name-6}}

我不知道有多少叶子会存在或根,或者csv中的行将进入什么顺序。我的问题是,有没有办法递归地从子节点直到父节点构建字典/列表?



感谢您的帮助!

解决方案

要将所有子节点分配给其父节点,您可以在节点列表上执行两次传递。第一个步骤将每个节点添加到 UserDict 。在第二遍中,每个节点的父节点保证在 UserDict 中,因此节点可以被添加到 children



要序列化为JSON a JSONEncoder

 #!/ usr / bin / env python 

import sys
import json
import UserDict

类Node :
def __init __(self,nid,parent,name):
self.nid = nid
self.parent = parent
self.children = []
self .name = name

class NodeDict(UserDict.UserDict):
def addNodes(self,nodes):
将每个节点作为子节点添加到父节点两个遍。
for i in(1,2):
for node in nodes:
self.data [node.nid] = node
if node.parent in self.data.keys():
if node.parent!=noneand
node not in self.data [node.parent] .children:
self.data [node .parent] .children.append(node)

class NodeJSONEncoder(json.JSONEncoder):
def default(self,node):
if type :
return {nid:node.nid,name:node.name,children:node.children}
raise TypeError({}不是Node的实例.format (node))

如果__name__ ==__main__:
nodes = []

open(sys.argv [1])as f:
for f.readlines()[1:]:
nid,parent,name = row.split()
nodes.append(Node(nid,parent,name))

nodeDict = NodeDict()
nodeDict.addNodes(nodes)

rootNodes = [nid的节点,nodeDict.items中的节点parent ==none]
在rootNodes中的rootNode:
print NodeJSONEncoder()。encode(rootNode)

结果:

  {name:test-name-4,nid :4,children:[
{name:test-name-10,nid:10,children:[
{name: test-name-1,nid:1,children:[
{name:test-name-7 ]},
{name:test-name-8,nid:8,children:[
{name:test-name- name:test-name-2,nid:2,children:[nid:9,children:[ ]},
{name:test-name-5,nid:5,children:[
{name:test-name- name:test-name-6,nid:6,children:nid:3,children:[ []}


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          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

and I'm looking for an output like this:

{"$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"}}

I have no idea how many "leaves" there will be or "roots", or what order the rows from the csv will come in. My question is, is there a way that I can recursively build a dictionary/list from a child node up to the parent? How can I produce a hierarchical tree from the "leaf" pieces of the tree in python?

Thanks for the help!

解决方案

To assign all child nodes to its parent, you can do two passes over the list of nodes. The first pass adds each node to a UserDict. In the second pass the parent of each node is guaranteed to be in the UserDict so the node can be added to the children of its parent.

To serialize to JSON a JSONEncoder can be used.

#!/usr/bin/env python

import sys
import json
import UserDict

class Node(object):
    def __init__(self, nid, parent, name):
        self.nid = nid
        self.parent = parent
        self.children = []
        self.name = name

class NodeDict(UserDict.UserDict):
    def addNodes(self, nodes):
        """ Add every node as a child to its parent by doing two passes."""
        for i in (1, 2):
            for node in nodes:
                self.data[node.nid] = node
                if node.parent in self.data.keys():
                    if node.parent != "none" and
                       node not in self.data[node.parent].children:
                        self.data[node.parent].children.append(node)

class NodeJSONEncoder(json.JSONEncoder):
    def default(self, node):
        if type(node) == Node:
            return {"nid":node.nid, "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]) as f:
        for row in f.readlines()[1:]:
            nid, parent, name = row.split()
            nodes.append(Node(nid, parent, name))

    nodeDict = NodeDict()
    nodeDict.addNodes(nodes)

    rootNodes = [node for nid, node in nodeDict.items()
                 if node.parent == "none"]
    for rootNode in rootNodes:
        print NodeJSONEncoder().encode(rootNode)

Result:

{"name": "test-name-4", "nid": "4", "children":[
     {"name": "test-name-10", "nid": "10", "children":[
         {"name": "test-name-1", "nid": "1", "children":[
            {"name": "test-name-7", "nid": "7", "children": []},
            {"name": "test-name-8", "nid": "8", "children":[
                {"name": "test-name-9", "nid": "9", "children": []}]}]},
         {"name": "test-name-2", "nid": "2", "children": []},
         {"name": "test-name-5", "nid": "5", "children":[
             {"name": "test-name-3", "nid": "3", "children": []}]}]}]}
{"name": "test-name-6", "nid": "6", "children": []}

这篇关于从python中的csv list创建一个json树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆