将size=x添加到JSON

2024-09-28 15:27:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我有下面的代码来基于;分隔的数据创建一个JSON文件。 导入csv 从集合导入defaultdict

def ctree():
    """ One of the python gems. Making possible to have dynamic tree structure.
    """
    return defaultdict(ctree)


def build_leaf(name, leaf):
    """ Recursive function to build desired custom tree structure
    """
    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()]

    return res


def main(delimter):
    tree = ctree()
    text = """
    something;cookie;chocolat
    something;cookie;milk
    something;gains;bread
    anything;protein;chicken
    """
    rows = [row.strip().split(delimter) for row in text.split("\n")]
    for row in rows:
        if row:
            leaf = tree[row[0]]
            for cid in range(1, len(row)):
                leaf = leaf[row[cid]]

    # building a custom tree structure
    res = []
    for name, leaf in tree.items():
        res.append(build_leaf(name, leaf))

    # printing results into the terminal
    import json
    print(json.dumps(res))


# so let's roll
main(";")

(来源:Convert csv to JSON tree structure?

这将产生以下输出:

[
  {
    "name": ""
  },
  {
    "name": "something",
    "children": [
      {
        "name": "cookie",
        "children": [
          {
            "name": "chocolat"
          },
          {
            "name": "milk"
          }
        ]
      },
      {
        "name": "gains",
        "children": [
          {
            "name": "bread"
          }
        ]
      }
    ]
  },
  {
    "name": "anything",
    "children": [
      {
        "name": "protein",
        "children": [
          {
            "name": "chicken"
          }
        ]
      }
    ]
  }
]

但是我想包含一个, "size" : 100,所以我有这样一个输出:

[
  {
    "name": ""
  },
  {
    "name": "something",
    "children": [
      {
        "name": "cookie",
        "children": [
          {
            "name": "chocolat", "size" : 100
          },
          {
            "name": "milk", "size" : 100
          }
        ]
      },
      {
etc.

所以实际上,如果一个项目被添加到3rd层,它需要添加, "size" : 100。我想知道是否仍然可以像上面那样使用递归?或者我应该把它改成嵌套循环(我不喜欢),以便能够“记住”当前层?如果不是,我如何在仍然使用递归的情况下实现这一点


Tags: nameinbuildtreeforsizecookiedef
1条回答
网友
1楼 · 发布于 2024-09-28 15:27:10

正如Markaos在注释中提到的,您只需要跟踪递归深度,以便知道何时向res["children"]中的每个dict添加额外的键值对。例如

def build_leaf(name, leaf, depth=0):
    """ Recursive function to build desired custom tree structure
    """
    res = {"name": name}
    depth += 1

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

我给了depth一个默认值0,所以您不需要修改main中对build_leaf的调用。你知道吗

生成的JSON如下所示(我使用了一个自定义编码器来生成更紧凑的输出)。你知道吗

[
  {"name": ""},
  {
    "name": "something",
    "children": [
      {
        "name": "cookie",
        "children": [
          {"name": "chocolat", "size": 100},
          {"name": "milk", "size": 100}
        ]
      },
      {
        "name": "gains",
        "children": [
          {"name": "bread", "size": 100}
        ]
      }
    ]
  },
  {
    "name": "anything",
    "children": [
      {
        "name": "protein",
        "children": [
          {"name": "chicken", "size": 100}
        ]
      }
    ]
  }
]

相关问题 更多 >