Python - 通过多级别1,1.1,1.1.1,1.1.2(分层)按名称附加到字典

时间:2017-02-24 12:15:08

标签: python json dictionary openpyxl

我使用openpyxl从excel文件中读取数据,最后提供一个json文件。问题是我无法找出一个算法来对json(或python字典)进行分层组织。

数据表格如下:

Table

输出应该是这样的:

{
'id'       : '1',
'name'     : 'first',
'value'    : 10,
'children': [ {
                'id'   : '1.1',
                'name' : 'ab',
                'value': 25,
                'children' : [
                  {
                   'id'   : '1.1.1',
                   'name' : 'abc' ,
                   'value': 16,
                   'children' : []
                  }
                 ]
                },
              {
                'id' : '1.2',
                 ...
          ]
}


这是我想出的,但我不能超越'1.1',因为'1.1.1'和'1.1.1.1'等等将与1.1相同。

from openpyxl import load_workbook
import re
from json import dumps

wb = load_workbook('resources.xlsx')
sheet = wb.get_sheet_by_name(wb.get_sheet_names()[0])
resources = {}
prev_dict = {}
list_rows = [ row for row in sheet.rows ]
for nrow in range(list_rows.__len__()):
    id = str(list_rows[nrow][0].value)
    val = {
    'id'        : id,
    'name'      : list_rows[nrow][1].value ,
    'value'     : list_rows[nrow][2].value ,
    'children'  : []
    }
    if id[:-2] == str(list_rows[nrow-1][0].value):
        prev_dict['children'].append(val)
    else:
        resources[nrow] = val
        prev_dict = resources[nrow]

print dumps(resources)

1 个答案:

答案 0 :(得分:2)

您需要按ID访问您的数据,因此第一步是创建一个字典,其中ID是键。为了便于数据操作,字符串"1.2.3"将转换为("1","2","3")元组。 (列表不允许作为dict键)。这使得父键的计算非常容易(key[:-1])。

通过这个准备,我们可以简单地填充每个项目的父项的子列表。但在此之前,需要添加一个特殊的ROOT元素。它是顶级项目的父级。

这就是全部。代码如下。

注意#1:它希望每个项目都有父项。这就是1.2.2被添加到测试数据中的原因。如果不是这样,请处理注明的KeyError

注意#2:结果是一个列表。

import json

testdata="""
1 first 20
1.1 ab 25
1.1.1 abc 16
1.2 cb 18
1.2.1 cbd 16
1.2.1.1 xyz 19
1.2.2 NEW -1
1.2.2.1 poz 40
1.2.2.2 pos 98
2 second 90
2.1 ezr 99
"""

datalist = [line.split() for line in testdata.split('\n') if line]
datadict = {tuple(item[0].split('.')): {
                'id': item[0],
                'name': item[1],
                'value': item[2],
                'children': []} 
            for item in datalist}
ROOT = ()
datadict[ROOT] = {'children': []} 
for key, value in datadict.items():
    if key != ROOT:
        datadict[key[:-1]]['children'].append(value)
        # KeyError = parent does not exist

result = datadict[ROOT]['children']
print(json.dumps(result, indent=4))