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

Python - append to dictionary by name with multilevels 1, 1.1, 1.1.1, 1.1.2 (hierarchical)

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

数据形式如下:

输出应该是这样的:

{
'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)

您需要通过 ID 访问您的数据,因此第一步是创建一个以 ID 为键的字典。为了便于数据操作,字符串 "1.2.3" 被转换为 ("1","2","3") 元组。 (列表不允许作为字典键)。这使得父密钥的计算非常容易 (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))