【问题标题】:How to Create a JSON Tree from a Tabulated Hierarchy in Python如何在 Python 中从列表层次结构创建 JSON 树
【发布时间】:2011-11-16 12:59:04
【问题描述】:

我确信在 Python 中(或在推送中,Javascript)中有一种优雅的方式来执行此操作,但对于我的生活,我看不到它......

我有一个 CSV 文件,格式如下:

ID, Name, Description
A, A-name,
A100, A100-name, A100-desc
A110, A110-name, A110-desc
A111, A111-name, A111-desc
A112, A112-name, A112-desc
A113, A113-name, A113-desc
A120, A120-name, A120-desc
A131, A131-name, A131-desc
A200, A200-name, A200-desc
B, B-name,
B100, B100-name, B100-desc
B130, B130-name, B130-desc
B131, B131-name, B131-desc
B140, B140-name, B140-desc

我想生成一个层次化的 JSON 结构,这样我就可以可视化 theJIT 中的数据。

var json = {  
  "id": "aUniqueIdentifier",  
  "name": "usually a nodes name",  
  "data": {  
    "some key": "some value",  
    "some other key": "some other value"  
   },  
  "children": [ *other nodes or empty* ]  
}; 

我的计划是将 ID 映射到 id,将 Name 映射到 name,Description 映射到 data.desc,并组织层次结构,以便:

  • 根是 A 和 B 的父级
  • A 是 A100 和 A200 的父代
  • A100 是 A110 和 A120 的父级
  • A110 是 A111、A112 和 A113 的父代
  • B 是 B100 的父级
  • B100 是 B130 和 B140 的父代
  • B130 是 B131 的父代

在其他常规的按 ID 排序中也有一个病态的情况,其中 A100 是 A131 的父级(预期的 A130 不存在)。

我希望找到一个优雅的 Python 解决方案来解决这个问题,但此刻它正在打败我,甚至忽略了病态的情况......

【问题讨论】:

  • 我不确定您提供的数据如何映射到您提供的 JSON 结构。你能澄清一下这个例子吗?
  • “数据”中应该包含什么?
  • 输入文件应该按这种方式排序还是可以随机排列?是否至少有一个父节点总是在子节点前面?

标签: python json thejit


【解决方案1】:

这样就可以了……

import csv
import json

class Node(dict):
    def __init__(self, (nid, name, ndescr)):
        dict.__init__(self)
        self['id'] = nid
        self['name'] = name.lstrip() # you have badly formed csv....
        self['description'] = ndescr.lstrip()
        self['children'] = []

    def add_node(self, node):
        for child in self['children']:
            if child.is_parent(node):
                child.add_node(node)
                break
        else:
            self['children'].append(node)

    def is_parent(self, node):
        if len(self['id']) == 4 and self['id'][-1] == '0':
            return node['id'].startswith(self['id'][:-1])
        return node['id'].startswith(self['id'])

class RootNode(Node):
    def __init__(self):
        Node.__init__(self, ('Root', '', ''))

    def is_parent(self, node):
        return True

def pretty_print(node, i=0):
    print '%sID=%s NAME=%s %s' % ('\t' * i, node['id'], node['name'], node['description'])
    for child in node['children']:
        pretty_print(child, i + 1)

def main():
    with open('input.csv') as f:
        f.readline() # Skip first line
        root = RootNode()
        for node in map(Node, csv.reader(f)):
            root.add_node(node)

    pretty_print(root)
    print json.dumps(root)

if __name__ == '__main__':
    main()

【讨论】:

  • 太棒了-谢谢。我是 Python 新手,没想到要像那样使用 Node 类!我的实际输入文件有一些非常混乱的列内容,但是这个讨厌的黑客对其进行了排序:#for node in map(Node, csv.reader(f)): for x in csv.reader(f): node=Node((x [0],x[1],x[2]))
猜你喜欢
  • 2022-01-27
  • 2011-03-10
  • 2017-04-18
  • 2019-07-03
  • 2018-11-19
  • 2012-08-16
  • 1970-01-01
  • 1970-01-01
  • 2021-04-26
相关资源
最近更新 更多