Python-在树结构中映射作业依赖项

Python-在树结构中映射作业依赖项,python,python-2.7,tree,mapping,Python,Python 2.7,Tree,Mapping,我有一个包含依赖项及其状态的作业列表。我希望遍历每个作业,并将它们的依赖关系映射为一棵树。当两个父依赖项的状态都为“完成”时,树将结束,这意味着遍历应该停止。我不确定是否应该使用递归,或者这是唯一的可能性。是否有本地映射工具或数据结构可以帮助我?我将迭代近10000个作业 伪代码 def map_depends(job_depends): for job in job_depends: if job.status = done: job_tree_

我有一个包含依赖项及其状态的作业列表。我希望遍历每个作业,并将它们的依赖关系映射为一棵树。当两个父依赖项的状态都为“完成”时,树将结束,这意味着遍历应该停止。我不确定是否应该使用递归,或者这是唯一的可能性。是否有本地映射工具或数据结构可以帮助我?我将迭代近10000个作业

伪代码

def map_depends(job_depends):
    for job in job_depends:
        if job.status = done:
            job_tree_map.append(job.name)
        else:
            map_depends(job.get('dependencies'))

def main():       
    for job in batch:
                if job.get('dependencies'):
                    map_depends(job.get('dependencies'))
对我所说内容的视觉描述

         -> job_depends1.status = done
main_job                                              -> job_depends3 = running -> job_depends6 = done
         -> job_depends2 = running......job_depends2  -> jon_depends4 = done
                                                      ->  job_depends5 = done

如果树相当深,使用递归算法可能会导致堆栈溢出,因为默认情况下CPython的嵌套调用限制为1000个。您可以使用
sys.setrecursionlimit
设置自己的限制值,但通常不建议这样做。因此,在您的情况下,最好以迭代的方式重写树遍历

例如,您可以编写一个函数,如用于树过滤和遍历的函数(不是伪代码):

可能相关的问题:


    • 树自然是递归数据结构,但是,任何可以递归编写的内容都可以使用显式堆栈迭代完成

      遗憾的是,直到CPython 3[34]才得到“yield from”,这使得递归生成器在早期版本中不切实际

      因此,如果您仍然以2.7为目标,那么您可能应该首先递归地编写东西,让它们以这种方式工作,然后以非递归方式编写生成器


      对于堆栈,许多Python开发人员都会在列表上使用append和pop,或acollections.deque。我可能出于抽象的目的而使用它,尽管在CPython中这通常比较慢。

      您的代码看起来有点不一致:
      job
      vs
      jobs
      job.get(取决于)
      vs
      job.get('dependencies')
      。谢谢。进行了更正。如果我的脚本导致堆栈溢出怎么办?它会关闭服务器吗?这是否可以包含?如果堆栈溢出,代码将抛出
      运行时错误:超过最大递归深度。与任何其他异常一样,除非被捕获,否则它将导致应用程序停机(此异常在Python中是可捕获的)。
      
      def walkjob(job):
          if job is None:
              return []
      
          result = [job, ]
          cursor = 0
      
          while cursor < len(result):
              job = result[cursor]
              result.extend(list(
                  filter(lambda j: j.done,
                  job.children)))
              cursor += 1
      
          return result
      
      >>> from bunch import Bunch
      >>> job = Bunch(value=1, done=True, children=[
      ...           Bunch(value=2, done=True, children=[]),
      ...           Bunch(value=3, done=True, children=[
      ...               Bunch(value=4, done=False, children=[]),
      ...               Bunch(value=5, done=True, children=[])])])
      ...
      >>> map(lambda j: (j.value, j.done), walkjob(job))
      [(1, True), (2, True), (3, True), (5, True)]