昨天在想如何将树形结构数据,即一层层、有父级子级关系的数据打印出来,而且还能表示层级关系。刚才想了想,感觉用递归比较合适,稍微琢磨了一下发现可行,下面就分享一下这个想法。
先准备一些数据,为了方便演示,我这里就用dict和list的组合来表示数据,另外我们规定每一行的索引即代表该行的id,比如第一行的数据,它的id就是0,第二行就是1,以此类推。
其中的parentid即其父级的id,如果为-1即表示没有父级,为顶级。
data=[{'parentid':-1,'name':'中国'},#id=0
      {'parentid':-1,'name':'美国'},#id=1
      {'parentid':0,'name':'广东省'},#id=2
      {'parentid':0,'name':'广西省'},#id=3
      {'parentid':1,'name':'阿拉斯加州'},
      {'parentid':1,'name':'加利福尼亚州'},
      {'parentid':2,'name':'深圳市'},
      {'parentid':2,'name':'广州市'},
      {'parentid':6,'name':'龙岗区'},
      {'parentid':6,'name':'福田区'},
      {'parentid':6,'name':'龙华区'},
      {'parentid':8,'name':'翻斗街道'},
      {'parentid':8,'name':'胡图街道'},
      {'parentid':8,'name':'英俊街道'}]
然后我们写一个根据id获得该行所有子数据的方法
def getChildren(data,id):
    children=[]
    for l in data:
        if l['parentid']==id:
            children.append(l)
    return children
接下来写一个递归打印子数据的方法,遍历打印出所有子元素,并根据层级在前面加多少倍的空格。这也是这个程序中比较关键的一部分。
def rollChildren(data,id,stair=0):
    children=getChildren(data,id)
    for c in children:
        print(stair*'   '+'├ '+c['name'])
        cid=data.index(c)
        rollChildren(data,cid,stair+1)
最后再写一个总的打印方法,它会先打印出顶级栏目,然后再调用rollChildren()按照层级打印出所有子数据。
def showTree(data):
    for l in data:
        if l['parentid']==-1:
            print(l['name'])
            pid=data.index(l)
            rollChildren(data,pid)
下面我们来测试一下

可以发现这个程序可以正确地将树形数据按层级打印出来啦。
在许多web项目上,这个功能应用还是很多的,比如网站多级目录的展示等等,稍微改改就可以应用到数据库和html上了。