变量tsv_data具有以下 struct :

[
{'id':1,'name':'bob','type':'blue','size':2},
{'id':2,'name':'bob','type':'blue','size':3},
{'id':3,'name':'bob','type':'blue','size':4},
{'id':4,'name':'bob','type':'red','size':2},
{'id':5,'name':'sarah','type':'blue','size':2},
{'id':6,'name':'sarah','type':'blue','size':3},
{'id':7,'name':'sarah','type':'green','size':2},
{'id':8,'name':'jack','type':'blue','size':5},
]

我想把它重组成:

[
{'name':'bob', 'children':[
    {'name':'blue','children':[
        {'id':1, 'size':2},
        {'id':2, 'size':3},
        {'id':3, 'size':4}
    ]},
    {'name':'red','children':[
        {'id':4, 'size':2}
    ]}
  ]},
{'name':'sarah', 'children':[
    {'name':'blue','children':[
        {'id':5, 'size':2},
        {'id':6, 'size':3},
    ]},
    {'name':'green','children':[
        {'id':7, 'size':2}
    ]}
  ]},
{'name':'jack', 'children':[
    {'name':'blue', 'children':[
        {'id':8, 'size':5}
    ]}
  ]}
]

阻碍我进步的是不知道每个主要类别的子元素列表中会有多少项.同样,我们也不知道哪些类别会出现.它可以是bluegreenred--这三个都可以,也可以是任意组合(比如只有redgreen或者只有green).

问题

我们如何才能设计出一种万无一失的方法,将tsv_data中包含的列表的基本列表编译成如上所述的多层分层数据 struct ?

推荐答案

给出你的主要类别作为一个列表:

categories = ['name', 'type']

您可以首先将输入数据转换为列表的嵌套字典,以便通过键更容易、更高效地访问子对象,而不是所需的输出格式-字典的嵌套列表:

tree = {}
for record in tsv_data:
    node = tree
    for category in categories[:-1]:
        node = node.setdefault(record.pop(category), {})
    node.setdefault(record.pop(categories[-1]), []).append(record)

tree将变成:

{'bob': {'blue': [{'id': 1, 'size': 2}, {'id': 2, 'size': 3}, {'id': 3, 'size': 4}], 'red': [{'id': 4, 'size': 2}]}, 'sarah': {'blue': [{'id': 5, 'size': 2}, {'id': 6, 'size': 3}], 'green': [{'id': 7, 'size': 2}]}, 'jack': {'blue': [{'id': 8, 'size': 5}]}}

然后,您可以使用递归函数将嵌套的字典转换为所需的输出 struct :

def transform(node):
    if isinstance(node, dict):
        return [
            {'name': name, 'children': transform(child)}
            for name, child in node.items()
        ]
    return node

这样transform(tree)人就会回来:

[{'name': 'bob', 'children': [{'name': 'blue', 'children': [{'id': 1, 'size': 2}, {'id': 2, 'size': 3}, {'id': 3, 'size': 4}]}, {'name': 'red', 'children': [{'id': 4, 'size': 2}]}]}, {'name': 'sarah', 'children': [{'name': 'blue', 'children': [{'id': 5, 'size': 2}, {'id': 6, 'size': 3}]}, {'name': 'green', 'children': [{'id': 7, 'size': 2}]}]}, {'name': 'jack', 'children': [{'name': 'blue', 'children': [{'id': 8, 'size': 5}]}]}]

演示:https://replit.com/@blhsing/NotableCourageousTranslations

Python-3.x相关问答推荐

我在创建Pandas DataFrame时感到困惑

查找值始终为零的行 pandas

为什么空列表也能起作用?

为什么不能用格式字符串 '-' 绘制点?

如何将 OLS 趋势线添加到使用 updatemenus 显示数据子集的 plotly 散点图图形对象?

过滤列表中的所有字典以使用特定键并忽略其他键?

txt 文件与不同的分隔符到整数列表

attrs 将 list[str] 转换为 list[float]

导入在不同目录中定义的函数

为什么 Multiprocessing 的 Lock 不会阻止其他进程使用对象?

SqlAlchemy - 从 oracle db 中检索长文本

Tkinter IntVar 返回 PY_VAR0 而不是值

python3源的类图查看器应用程序

逗号分隔列表的 argparse 操作或类型

在 sklearn.decomposition.PCA 中,为什么 components_ 是负数?

判断对 python 3 支持的要求

如何模拟 Django 模型对象(及其方法)?

计数大于Pandas groupby 中的值的项目

如何修复:cx_Oracle.DatabaseError:DPI-1047:找不到 64 位 Oracle 客户端库 - Python

注册 Celery 基于类的任务