代码之家  ›  专栏  ›  技术社区  ›  Alex

使用递归python函数嵌套导航菜单

  •  2
  • Alex  · 技术社区  · 16 年前

    我想将此数据结构呈现为无序列表。

    menu = [
             [1, 0],
               [2, 1],
               [3, 1],
                 [4, 3],
                 [5, 3],
                   [6, 5],
             [7,1]
            ]
    

    [n][0]是关键
    [n][1]引用父密钥

    所需输出为:

    <ul>
    <li>Node 1</li>
    
      <ul>
      <li>Node 2</li>
      <li>Node 3</li>
    
        <ul>
        <li>Node 4</li>
        <li>Node 5</li>
    
          <ul>
          <li>Node 6</li>
          </ul>
    
        </ul>
    
       <li>Node 7</li>
       </ul>
    
    </ul>
    

    我可能不需要递归就可以做到这一点,但那不会很有趣。用递归解决这个问题最有效的方法是什么?

    谢谢!

    2 回复  |  直到 13 年前
        1
  •  3
  •   Adam    16 年前
    def render(nodes, parent = 0):
        if parent not in nodes:
            return
        print('<ul>')
        for n in nodes[parent]:
            print('<li>Node %d</li>' % n)
            render(nodes, n)
        print('</ul>')
    

    这是输出

    >>> nodes = {}
    >>> for n in menu:
        if n[1] not in nodes:
            nodes[n[1]] = []
        nodes[n[1]].append(n[0])
    >>> render(nodes)
    <ul>
    <li>Node 1</li>
    <ul>
    <li>Node 2</li>
    <li>Node 3</li>
    <ul>
    <li>Node 4</li>
    <li>Node 5</li>
    <ul>
    <li>Node 6</li>
    </ul>
    </ul>
    <li>Node 7</li>
    </ul>
    </ul>
    
        2
  •  2
  •   Johannes Charra    16 年前

    我不会使用两个元素列表,即使您的结构如此简单。使用一些 TreeNode 然后给它一个适当的 __str__ 方法,例如

    class TreeNode(object):
        # ...
        # methods for adding children (instances of TreeNode again) etc.
    
        def __str__(self):
            ret = "<li>%s" % self.value
    
            if self.children:
                children = "".join([str(c) for c in self.children])
                ret += "<ul>%s</ul>" % children 
            ret += "</li>"
    
            return ret
    

    …或者类似的。但是没有测试。将整棵树的表示包含在 <ul> 标签。