Python转换为父/子JSON [英] Python to parent/child JSON

查看:121
本文介绍了Python转换为父/子JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Python将数据从CSV转换为JSON,格式如下: https://gist.github.com/mbostock/1093025 ,以便我可以修改 http://d3js.org/示例.

I'm trying to use Python to turn data from a CSV into a JSON with the format found here: https://gist.github.com/mbostock/1093025 so that I can modify some http://d3js.org/ examples.

我发现了一些有关如何进行类似转换的文章,但没有什么完全像嵌套的{'name': name, 'children' = []}格式.

I have found some posts on how to do similar transformations, but nothing exactly like the nested {'name': name, 'children' = []} format.

对于test.csv:

For the test.csv:

Team,Task,Country,ID
Team A,Processing,CA,5
Team A,Review,CA,45
Team B,Processing,US,76
Team B,Processing,CA,676
Team B,Support,US,2345
Team C,Processing,US,67
Team C,Review,US,734
Team C,Support,US,34

输出应如下所示:

{
 "name": "Flare",
 "children": [
  {
   "name": "Team A",
   "children": [
    {
     "name": "Processing",
     "children": [
      {"name": "CA", "size": 5}
     ]
    },
    {
     "name": "Review",
     "children": [
      {"name": "CA", "size": 45}
     ]
    }
   ]
  },
  {
   "name": "Team B",
   "children": [
    {
     "name": "Processing",
     "children": [
      {"name": "US", "size": 76},
      {"name": "CA", "size": 676}
     ]
    },
    {
     "name": "Support",
     "children": [
      {"name": "US", "size": 2345}
     ]
    }
   ]
  }, 
  {
   "name": "Team C",
   "children": [
    {
     "name": "Processing",
     "children": [
      {"name": "US", "size": 67}
     ]
    },
    {
     "name": "Review",
     "children": [
      {"name": "US", "size": 734}
     ]
    },
    {
     "name": "Support",
     "children": [
      {"name": "US", "size": 34}
     ]
    }
   ]
  }
 ]
}

据我所知(我知道这很糟糕):

This is as far as I have been able to get (I know it's pretty bad):

import csv
import json

children = []

#create a list of lists from CSV
reader = csv.reader(open('//corp.bloomberg.com/pn-dfs/AllLinks/Users/jdesilvio/Desktop/test.csv', 'rb'))
reader.next() 
for row in reader:
    children.append(row)

#create tree root
tree = {'name': "flare", 'children': []}

#create a generic subtree
subtree = {'name': 0, 'children': []}

for i in children:
    #if the first element in i doesn't equal name, then we know that it's a different group 
    if i[0] != subtree['name']:
        #so we append the current group
        tree['children'].append({'name': subtree['name'], 'children': subtree['children']})
        #start a new group
        subtree['children'] = []
        #and rename the subtree
        subtree['name'] = i[0]
    else:
        #then start appending pieces to the new group
        subtree['children'].append(i[1:len(i)])

#remove the generic starting name
tree['children'] = tree['children'][1:]

print json.dumps(tree, indent=1)

哪个产量:

{
 "name": "flare", 
 "children": [
  {
   "name": "Team A", 
   "children": [
    [
     "Review", 
     "CA", 
     "45"
    ]
   ]
  }, 
  {
   "name": "Team B", 
   "children": [
    [
     "Processing", 
     "CA", 
     "676"
    ], 
    [
     "Support", 
     "US", 
     "2345"
    ]
   ]
  }
 ]
}

这看起来朝着正确的方向发展,但是即使我能够嵌套第一级,我也不知道如何以通用方式嵌套更多的级.

This looks like it is headed in the right direction, but even if I was able to get the first level nested, I'm not sure how to nest more levels in a generic way.

推荐答案

填充树是最清晰的解决方案.但是,使用字典进行遍历不是一个好主意.我建议为每个树节点创建一个帮助器类,将其用于填充数据,然后将结果转换为JSON:

Populate the tree is the most clear solution. However, using a dict for traversing is not a good idea. I suggest to create a helper class for each tree node, use it for populating data and then convert result to JSON:

import csv
import json


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

    def child(self, cname, size=None):
        child_found = [c for c in self.children if c.name == cname]
        if not child_found:
            _child = Node(cname, size)
            self.children.append(_child)
        else:
            _child = child_found[0]
        return _child

    def as_dict(self):
        res = {'name': self.name}
        if self.size is None:
            res['children'] = [c.as_dict() for c in self.children]
        else:
            res['size'] = self.size
        return res


root = Node('Flare')

with open('/tmp/test.csv', 'r') as f:
    reader = csv.reader(f)
    reader.next()
    for row in reader:
        grp1, grp2, grp3, size = row
        root.child(grp1).child(grp2).child(grp3, size)

print json.dumps(root.as_dict(), indent=4)

这篇关于Python转换为父/子JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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