python - 从最后一列向动态树添加大小

标签 python json tree

我需要创建一个嵌套的字典结构,其中每个级别的子级数量可以不同。

Appending “size” element to last json child element for a sunburst diagram 这个问题涵盖了树的创建,除了我需要从最后一列中获取大小。

鉴于我的标签在级别之间重复,并且每个级别可以具有与终端级别相同的标签“abc”,以及下一级的父级 - 我稍微修改了此处的代码(以避免子分支中的重复) 。然而,我无法指定大小,它存储在最后一列中,并且应该替换每个叶端中的 1。我知道我需要将行中的值传递到递归循环 build_leaf,但似乎不知道如何进行。

Sample data

import csv
from collections import defaultdict
import json

def ctree():
    return defaultdict(ctree)


def build_leaf(name, leaf):        
    if len(name)==0:
        res={"name":"last node"}
        res['size']=1
    else:
        res = {"name": name}

        # add children node if the leaf actually has any children
        if len(leaf.keys())>0:
            res["children"] = [build_leaf(k, v) for k, v in leaf.items()]
        else:
            res['size'] = 1

    return res

def main():
    tree = ctree()
    # NOTE: you need to have test.csv file as neighbor to this file
    with open('./inpfile.csv') as csvfile:
        reader = csv.reader(csvfile)
        header = next(reader)  # read the header row        
        i=0
        for row in reader:
            # usage of python magic to construct dynamic tree structure and
            # basically grouping csv values under their parents
            leaf = tree[row[0]]
            size=row[-1]

            for value in row[1:-1]:
                leaf = leaf[value]

    # building a custom tree structure
    res = []

    for name, leaf in tree.items():
        res.append(build_leaf(name, leaf))

    # printing results into the terminal
    print(json.dumps(res, indent=2))
    with open('paths.json', 'w') as fp:
        json.dump(res, fp)


main()

上述数据的最终输出应类似于:

[
  {
    "name": "A1",
    "children": [
      {
        "name": "A2",
        "children": [
          {
            "name": "A1",
            "children": [
              {
                "name": "A2",
                "children": [
                  {
                    "name": "A3",
                    "size": 80
                  }
                ]
              }
            ]
          },
          {
            "name": "A3",
            "children": [
              {
                "name": "A2",
                "children": [
                  {
                    "name": "A3",
                    "size": 169
                  }
                ]
              },
              {
                "name": "exit site",
                "size": 764
              }
            ]
          },
          {
            "name": "A6",
            "children": [
              {
                "name": "A3",
                "children": [
                  {
                    "name": "exit site",
                    "size": 127
                  }
                ]
              }
            ]
          },
          {
            "name": "exit site",
            "size": 576
          }
        ]
      }
    ]
  }
]

最佳答案

如果有人偶然发现同样的问题 - 我可以通过创建另一个递归循环来从嵌套叶子中检索大小来使其工作(感谢 Douglas 的帮助)。

def ctree():
    return defaultdict(ctree)

def get_size(leaf1):
    for k,v in leaf1.items():
        if k=="size":
            return v
        else:
            return get_size(v)


def build_leaf(name, leaf):

    if len(name)==0:
        res={"name":"exit site"}
        res['size']=int(get_size(leaf))

    else:
        res = {"name": name}

        # add children node if the leaf actually has any children
        if not leaf["size"]:
            res["children"] = [build_leaf(k, v) for k, v in leaf.items() if not k == "size" ]
        else:
            res['size'] = int(get_size(leaf))

    return res

def make_json(inpfile,outjson):
    tree = ctree()
    # NOTE: you need to have test.csv file as neighbor to this file
    with open("./filepath.csv") as csvfile:
        reader = csv.reader(csvfile)
        header = next(reader)  # read the header row        

        for row in reader:
            # usage of python magic to construct dynamic tree structure and
            # basically grouping csv values under their parents
            leaf = tree[row[0]]
            size=row[-1]

            for value in row[1:-1]:
                leaf = leaf[value]
            if len(row) < 6:
                leaf["exit site"]["size"]=size
            else:
                leaf["size"]=size

    # building a custom tree structure
    res = []

    for name, leaf in tree.items():
        res.append(build_leaf(name, leaf))

    with open(outjson, 'w') as fp:
        json.dump(res, fp)

关于python - 从最后一列向动态树添加大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58357957/

相关文章:

c - 如何释放包含 char 指针的 BST?

python - 如何解析 json 以获取数组中特定键的所有值?

python - 与 python 中长时间运行的任务通信

javascript - JQuery 从 REST 和 JSON 获取数据源

javascript - xlsx 到 json 并带有空单元格

python - 将路径附加到 python 程序

c++ - 从 B 树中删除一个节点

python - 类型错误 : __array__() takes 1 positional argument but 2 were given

python - Django manage.py 迁移 ImportError

ruby-on-rails - 仅将 JSON curl 请求的值保存到 RoR 中的 PG 数据库