You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

合并嵌套字典生成D3旭日图所需JSON文件的问题

如何合并深层嵌套的分类字典(用于D3旭日图)

看起来你需要的是一个递归的嵌套字典合并逻辑——核心是在每一层级找到同名同类型的节点,合并它们的子节点,而不是直接重复添加。我来帮你梳理解决方案:

问题分析

你当前的代码问题在于merge函数没有针对嵌套层级做节点匹配:它只是简单合并字典,导致同一层级的同名节点(比如"Bacteria")被重复创建,而不是找到已存在的节点并合并其子节点。

解决方案:递归合并节点

我们需要写一个递归函数,针对每个节点的children数组,根据name和tax字段匹配已存在的节点:

  1. 如果两个节点的name和tax完全一致,就递归合并它们的children
  2. 如果目标节点的children里没有匹配的节点,就把新节点添加进去
  3. 对于叶子节点(带有size字段的节点),可以选择直接追加或者累加size(根据你的需求调整)

完整代码实现

def merge_nodes(target_node, new_node):
    """递归合并两个嵌套的分类节点"""
    # 首先检查当前节点是否匹配(name和tax都一致才是同一节点)
    if target_node['name'] == new_node['name'] and target_node['tax'] == new_node['tax']:
        # 如果是叶子节点(有size字段),直接追加子节点(若需累加size可修改此处逻辑)
        if 'size' in new_node:
            target_node.setdefault('children', []).append(new_node)
            return target_node
        
        # 处理子节点:遍历新节点的children,尝试合并到目标节点的children中
        target_children = target_node.setdefault('children', [])
        for new_child in new_node.get('children', []):
            # 寻找目标子节点中是否有匹配项
            matched = False
            for target_child in target_children:
                if target_child['name'] == new_child['name'] and target_child['tax'] == new_child['tax']:
                    merge_nodes(target_child, new_child)
                    matched = True
                    break
            # 没有匹配的就添加新子节点
            if not matched:
                target_children.append(new_child)
        return target_node
    else:
        # 当前节点不匹配,直接返回新节点(调用方会处理添加逻辑)
        return new_node

def merge_dicts(dict_list):
    """合并字典列表为单个嵌套字典"""
    if not dict_list:
        return {}
    # 初始化结果为第一个字典的深拷贝,避免修改原数据
    import copy
    result = copy.deepcopy(dict_list[0])
    # 遍历剩余字典,逐个合并到结果中
    for d in dict_list[1:]:
        merge_nodes(result, d)
    return result

使用示例

假设你的字典列表是tempDicts,调用方式如下:

# 模拟你的多个小字典数据
tempDicts = [
    { "name": "root", "tax": "Tax level: domain", "children": [ { "name": "Bacteria", "tax": "Tax level: Kingdom", "children": [ { "name": "Firmicutes", "tax": "Tax level: Phylum", "children": [ { "name": "Bacillidae", "tax": "Tax level: Class", "children": [ { "name": "Bacillinae", "tax": "Tax level: Order", "children": [ { "name": "Bacillini", "tax": "Tax level: Family", "children": [ { "name": "Bacillus", "tax": "Tax level: Genus", "children": [ { "name": "", "size": 5, "tax": "Tax level: Species" } ] } ] } ] } ] } ] } ] },
    { "name": "root", "tax": "Tax level: domain", "children": [ { "name": "Bacteria", "tax": "Tax level: Kingdom", "children": [ { "name": "Firmicutes", "tax": "Tax level: Phylum", "children": [ { "name": "Firmicutes", "tax": "Tax level: Class", "children": [ { "name": "Tissierellia", "tax": "Tax level: Order", "children": [ { "name": "unclassified Tissierellia", "tax": "Tax level: Family", "children": [ { "name": "Tepidimicrobium", "tax": "Tax level: Genus", "children": [ { "name": "", "size": 5, "tax": "Tax level: Species" } ] } ] } ] } ] } ] } ] },
    { "name": "root", "tax": "Tax level: domain", "children": [ { "name": "Thermotogae", "tax": "Tax level: Phylum", "children": [ { "name": "Thermotogae", "tax": "Tax level: Class", "children": [ { "name": "Thermotogales", "tax": "Tax level: Order", "children": [ { "name": "Thermotogaceae", "tax": "Tax level: Family", "children": [ { "name": "Thermotoga", "tax": "Tax level: Genus", "children": [ { "name": "", "size": 5, "tax": "Tax level: Species" } ] } ] } ] } ] } ] } ] }
]

# 执行合并
merged_result = merge_dicts(tempDicts)

# 格式化输出结果(方便查看)
import json
print(json.dumps(merged_result, indent=2))

代码说明

  1. merge_nodes函数:核心递归逻辑,负责匹配并合并单个节点及其子节点,确保相同层级的同名节点不会重复创建。
  2. merge_dicts函数:处理整个字典列表,从第一个字典开始,依次合并后续的每个字典到结果中,避免了原代码中容易出现的索引越界问题。
  3. 叶子节点处理:示例中是直接追加叶子节点(相同species的节点会并列),如果需要累加size,可以修改叶子节点的处理逻辑,比如找到同名的叶子节点后累加size而不是追加。

内容的提问来源于stack exchange,提问作者Shane P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:26:49