【问题标题】:How do I build a tree dynamically in Python如何在 Python 中动态构建树
【发布时间】:2014-02-15 05:22:32
【问题描述】:

一个初学者 Python/编程问题...我想在 Python 中构建一个树形结构,最好基于字典。我发现代码可以巧妙地做到这一点:

Tree = lambda: collections.defaultdict(Tree)
root = Tree()

这可以很容易地填充为:

 root['toplevel']['secondlevel']['thirdlevel'] = 1
 root['toplevel']['anotherLevel'] = 2
 ...etc.

我想动态填充关卡/叶子,以便我可以根据需要添加任意多的关卡,并且叶子可以在任何关卡的位置。我该怎么做?

非常感谢任何帮助。

【问题讨论】:

  • 您可以按原样使用此代码。您可以根据需要添加任意数量的级别。你到底有什么问题?
  • 我不知道我之前有多少关卡,所以我希望能够动态添加它们而不是硬编码它们
  • 这是递归人,你试过我的答案吗?您所要做的就是将对象类型从标准对象更改为字典
  • 你能举个例子说明你想写什么样的代码,或者你想把一些输入处理成树吗?

标签: python recursion dictionary


【解决方案1】:

这个

root['toplevel']['secondlevel']['thirdlevel'] = 1

也可以这样:

node = root
for key in ('toplevel', 'secondlevel'):
    node = node[key]
node['thirdlevel'] = 1

我希望这能给你一个想法。

【讨论】:

    【解决方案2】:

    啊!当我开始编码时,这对我来说也是一个问题,但我们中最优秀的人很早就遇到了。

    注意;这适用于当你的树深入 N 层时。其中 N 介于 0 和无穷大之间,即;你不知道它能走多深;它可能只有第一级,也可能达到第 20 级

    您的问题是一般编程问题;读一棵树,可以是任意数量的深度,解决方案是;递归。

    无论何时在树结构中阅读,你都必须;

    1 - 建立一个对象 2 - 检查对象是否有孩子 2a - 如果对象有子对象,则为每个子对象执行步骤 1 和 2。

    这里有一个用于执行此操作的 python 代码模板;

    def buildTree(treeObject):
       currObject = Hierarchy()
       currObject.name = treeObject.getName()
       currObject.age = treeObject.getAge()
       #as well as any other calculations and values you have to set for that object
    
       for child in treeObject.children:
          currChild = buildTree(child)
          currObject.addChild(currChild)
       #end loop
    
       return currObject
    

    【讨论】:

      【解决方案3】:

      你可以简单地用一个实用函数来做,像这样

      def add_element(root, path, data):
          reduce(lambda x, y: x[y], path[:-1], root)[path[-1]] = data
      

      你可以像这样使用它

      import collections
      tree = lambda: collections.defaultdict(tree)
      root = tree()
      add_element(root, ['toplevel', 'secondlevel', 'thirdlevel'], 1)
      add_element(root, ['toplevel', 'anotherlevel'], 2)
      print root
      

      输出

      defaultdict(<function <lambda> at 0x7f1145eac7d0>,
          {'toplevel': defaultdict(<function <lambda> at 0x7f1145eac7d0>,
             {'secondlevel': defaultdict(<function <lambda> at 0x7f1145eac7d0>,
                  {'thirdlevel': 1}),
              'anotherlevel': 2
             })
          })
      

      如果你想以递归的方式实现,你可以从当前root获取第一个元素并获取子对象,然后从path中剥离第一个元素,用于下一次迭代。

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

      【讨论】:

      • 这很有帮助,谢谢。但是,如果我想一个一个地构建关卡怎么办。即,我并没有事先准备好所有的路径。我想构建第一层,如果我有它的子节点,构建另一个层,......等等。
      • 他需要一个递归函数人,检查问题中的标签,我认为他需要指导如何使用递归构建一个深入 N 层的对象树。你有 23.4k 代表,你是这方面的专家
      • @pythonian29033 我只是设法提供了一个基本的递归版本,请检查:)
      • @user252652 只要您知道path,您就可以使用任一版本在获取数据时添加元素。
      • @thefourtheye 谢谢,我应该很快地把我的答案改成这么简单,但至少我得到了赞成:D
      猜你喜欢
      • 1970-01-01
      • 2019-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多