变量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相关问答推荐

根据收件箱内部的值以行降序的特定顺序重新排序列

在Python中从mySQL获取多行

如何获得大Pandas 的常见时间间隔

基于另一个数据帧计算总和

给定panda代码的分组和百分比分布pyspark等价

torch.stack([t1, t1, t1], dim=1)与torch.hstack([t1, t1, t1])之间有什么区别?

在REPLACE INTO中引用变量会抛出sqlite3.OperationalError

如何键入提示函数,在 Python 中通过类decorator 添加到类中

将 pandas Timestamp() 转换为 datetime.datetime() 以支持 peewee DateTimeField()

如果网站加载时间过长,如何强制 Selenium 刷新

XPATH:使用 .find_elements_by_xpath 为未知数量的 xpath 输入值

Python多进程:运行一个类的多个实例,将所有子进程保留在内存中

使用 Python 解析 JSON 嵌套字典

在python中基于列表理解的条件下跳过元素

UnicodeDecodeError:utf-8编解码器无法解码位置 1 的字节 0x8b:无效的起始字节,同时读取Pandas中的 csv 文件

无法在 Windows Python 3.5 上安装 Levenshtein 距离包

pip install dryscrape 失败并显示错误:[Errno 2] 没有这样的文件或目录:'src/webkit_server'?

具有不均匀间隙的 Python 范围

如何在 Python 3.2 中退出?

字典理解中的操作顺序