【问题标题】:Python - Building A Nested tree DynamicallyPython - 动态构建嵌套树
【发布时间】:2019-04-29 10:17:33
【问题描述】:

我正在尝试使用 python 构建树层次结构,可以说我有他的结构,我需要能够动态添加更多子级,例如 Bannana。 我觉得我的问题有点不清楚

更新:我需要创建一个这样的结构,但是值会改变,所以我需要创建函数来传递一个 int 并创建 Apple(Children) 的数量并做同样的事情为柠檬和所有其他孩子。苹果节点也是根节点。

Apple
   Bannana
   Lemon
      Juice
        Drink
   Watermelon
       Red
         Round

但是我可以有一个完全不同的结构,例如

Apple
   Bannana
   Lemon
      Juice
        Drink
          Watermelon
       Red
          Round

Json 输出将是

{
    'Apple': 'Fruit',
    'children': [{
        'Bannana': 'fruit',
        'children': None
    },  {
        'Lemon': 'Fruit',
        'children': [{
            'Juice': 'Food',
            'children': [{
                'Drink': 'Action',
                'children': None
             And so on...

如何使层次结构动态化?例如特定父级下的行数?

我已经从我找到的示例中尝试过类似的方法

import collections
def add_element(root, path, data):
    if len(path) == 1:
        root[path[0]] = data
    else:
        add_element(root[path[0]], path[1:], data)

count = 1


tree = lambda: collections.defaultdict(tree)
root = tree()
n= 10
for i in range(1,n):
    path_list= ['Apple', 'Lemon', 'Juice' + str(count)]
    print (path_list)
    count += 1
    add_element(root,path_list, 1 )
print (root)

编辑 1

根据答案,我稍微修改了代码

args = {'Apple': 'Apple', 'Lemon': 'Lemon', 'Juice': 'Juice', 'Drink': 'Drink'}

s = """
{Apple}
   {Lemon}
      {Juice}
         {Drink}
""".format(**args)

def group_data(vals):
  if len(vals) == 1:
     return {vals[0]:'Fruit', 'Children':None}
  new_data = [list(b) for _, b in itertools.groupby(vals, key=lambda x:bool(re.findall('^\s', x)))]
  new_group = [[new_data[i], new_data[i+1]] for i in range(0, len(new_data), 2)]
  result = []
  for a, b in new_group:
     result.extend([{i:'Fruit', 'Children':None} for i in a[:-1]])
     result.append({a[-1]:'Fruit', 'Children':group_data([re.sub('^\s{3}', '', c) for c in b])})
  return result

_new_data = [i.strip('\n') for i in filter(None, s.split('\n'))]


print(json.dumps(group_data(_new_data), indent=4))

这工作正常,但它仍然是硬编码的,这不是我想要的。

【问题讨论】:

    标签: python json algorithm recursion tree


    【解决方案1】:

    您可以分析每个水果之前的空白:

    s = """
    Apple
       Bannana
       Lemon
          Juice
             Drink
                Watermelon
          Red
             Round
    """
    

    import itertools, re
    def group_data(vals):
      if len(vals) == 1:
         return {vals[0]:'Fruit', 'Children':None}
      new_data = [list(b) for _, b in itertools.groupby(vals, key=lambda x:bool(re.findall('^\s', x)))]
      new_group = [[new_data[i], new_data[i+1]] for i in range(0, len(new_data), 2)]
      result = []
      for a, b in new_group:
         result.extend([{i:'Fruit', 'Children':None} for i in a[:-1]])
         result.append({a[-1]:'Fruit', 'Children':group_data([re.sub('^\s{3}', '', c) for c in b])})
      return result
    
    _new_data = [i.strip('\n') for i in filter(None, s.split('\n'))]
    

    import json
    print(json.dumps(group_data(_new_data), indent=4))
    

    输出:

    [
         {
           "Apple": "Fruit",
           "Children": [
             {
                "Bannana": "Fruit",
                "Children": null
               },
               {
                   "Lemon": "Fruit",
                   "Children": [
                      {
                          "Juice": "Fruit",
                           "Children": [
                                {
                                 "Drink": "Fruit",
                                 "Children": {
                                     "Watermelon": "Fruit",
                                     "Children": null
                                  }
                              }
                          ]
                      },
                      {
                           "Red": "Fruit",
                           "Children": {
                              "Round": "Fruit",
                              "Children": null
                         }
                      }
                  ]
              }
           ]
        }
    ]
    

    【讨论】:

    • 这是一个很好的答案,但如果我有动态值怎么办?
    • @WojtekT 这适用于任何有效的结构。你能澄清一下“动态值”是什么意思吗?
    • 动态我的意思是例如我想要 10 个 RootChild 节点然后我想在每秒 RootChild 节点中放入 2 个子节点
    猜你喜欢
    • 1970-01-01
    • 2016-08-16
    • 2011-11-13
    • 1970-01-01
    • 2016-04-02
    • 2020-11-17
    • 2014-02-15
    • 1970-01-01
    • 2010-11-04
    相关资源
    最近更新 更多