【问题标题】:How to perform recursion in python dictionary如何在python字典中执行递归
【发布时间】:2013-03-13 06:57:53
【问题描述】:

我有一本字典,我想用它来创建一棵树。这个想法是获取指定索引的,将其附加到列表中。将此值用作字典下一项中的索引,并重复该过程,直到我们得到一个 None

我的字典

dict = {
         'A' : 'AF',
         'BF': 'B',
         'AF': 'Z',
         'Z' : None,
         'B' : 'B'
       }

我可以循环遍历字典并获得第一个值,但我无法更好地递归循环遍历字典。

注意 x 是我要指定的索引参数。即 A、BF、AF、Z 或 B

def tree(x,dict):
   result = []
   for value in dict:
      result.append(value)
    #stuck somewhere here. 
    #I would like to use this value as an index again and pick next value. 
    #Do this until I have no further relation

   #print final results in a list
   print result

当调用 tree(x,dict) 时,取 x = 'A' 预期的结果应该是:

['A','AF','Z']

感谢您的帮助和贡献。

【问题讨论】:

  • 递归是必须的吗?
  • 不是必须的,但我也考虑到了性能。我可能需要阅读一个非常大的字典数据集。

标签: python loops data-structures recursion


【解决方案1】:

非递归版本更快,但有一个看起来不错

>>> def tree(D, x):
        if x is None: 
            return []
        else: 
            return [x] + tree(D, D[x])


>>> tree(D, 'A')
['A', 'AF', 'Z']

或者作为单行:

def tree(D, x):
    return [] if x is None else [x] + tree(D, D[x])

这将具有二次运行时,因为它每次添加两个列表,但如果您想要性能,您只需使用 .append,然后使用循环会更实用。

【讨论】:

    【解决方案2】:
    def tree(x,dict):
        old_value = x
        while True:
            value = dict.get(old_value)
            if not value:
                break
            result.append(value)
        print result
    

    【讨论】:

    • 谢谢你。让我去递归的,它很符合我的要求。我从中学到了一些东西。谢谢 wRAR
    【解决方案3】:

    你也可以试试递归生成器:

    # This will loop "forever"
    data = {                                                                        
      'A' : 'AF',                                                          
      'BF': 'B',                                                           
      'AF': 'Z',                                                           
      'Z' : None,                                                          
      'B' : 'B'                                                            
    }                                                                      
                                                                                                                                                       
    def tree(key):                                                                  
      value = data.get(key)                                                         
      yield key                                                                     
      if value is not None:                                                         
        for value in tree(value):                                                   
          yield value                                                               
                                                                                
    for value in tree("A"):                                                         
      # Do something with the value     
    

    编辑:上述建议的方法无法检测循环,并将循环直到达到最大递归深度。

    下面的递归方法会跟踪访问过的节点以检测循环,如果是则退出。关于如何找到循环的最易理解的描述来自这个answer

    data = {
      'A' : 'AF',
      'BF': 'B',
      'AF': 'Z',
      'Z' : None,
      'B' : 'B'
    }
    
    def visit_graph(graph, node, visited_nodes):
        print "\tcurrent node: ", node, "\tvisited nodes: ", visited_nodes
        # None means we have reached a node that doesn't have any children
        if node is None:
            return visited_nodes
        # The current node has already been seen, the graph has a cycle we must exit
        if node in visited_nodes:
            raise Exception("graph contains a cycle")
        # Add the current node to the list of visited node to avoid cycles
        visited_nodes.append(node)
        # Recursively call the method with the child node of the current node
        return visit_graph(graph, graph.get(node), visited_nodes)
    
    
    # "A" does not generate any cycle
    print visit_graph(data, "A", [])
    
    # Starting at "B" or "BF" will generate cycles
    try:
        print visit_graph(data, "B", [])
    except Exception, e:
        print e
    
    try:
        print visit_graph(data, "BF", [])
    except Exception, e:
        print e
    

    【讨论】:

      猜你喜欢
      • 2017-02-27
      • 1970-01-01
      • 1970-01-01
      • 2018-02-21
      • 2014-12-07
      • 2013-01-15
      • 2021-11-22
      • 1970-01-01
      • 2022-11-03
      相关资源
      最近更新 更多