Python:递归打印树

2024-10-02 18:18:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经实现了一个REST API,它返回以下信息:

Parent/SiteA
Parent/SiteB
Parent/SiteC
Parent/SiteD
Parent/SiteD/xyz
Parent/SiteE
Parent/SiteD/xyz/Site8
Parent/SiteE/def
Parent/SiteF/Site3
Parent/SiteF
Parent/SiteF/Site4
Parent/SiteF/Site5

我想打印如下(树形结构):

Parent
   SiteA
   SiteB
   SiteC
   SiteD 
      xyz
         Site8
   SiteE
      def
   SiteF  
      Site3
      Site4
      Site5

父站点下可以有无限数量的站点,因此需要某种形式的递归

我真的不知道有什么可能的解决办法,尝试了很多事情,浪费了很多时间,但似乎找不到解决办法。有人愿意提供提示吗


Tags: 站点defparentxyz解决办法siteasite3site5
2条回答

根据sal的评论,如果您已经有了路径列表,那么这很容易,并且不需要递归:

>>> info = [
...     "Parent/SiteA",
...     "Parent/SiteB",
...     "Parent/SiteC",
...     "Parent/SiteD",
...     "Parent/SiteD/xyz",
...     "Parent/SiteE",
...     "Parent/SiteD/xyz/Site8",
...     "Parent/SiteE/def",
...     "Parent/SiteF/Site3",
...     "Parent/SiteF",
...     "Parent/SiteF/Site4",
...     "Parent/SiteF/Site5",
... ]
>>>
>>> info.sort()
>>> for line in info:
...     print('   '*line.count('/') + line.split('/')[-1])
...
   SiteA
   SiteB
   SiteC
   SiteD
      xyz
         Site8
   SiteE
      def
   SiteF
      Site3
      Site4
      Site5

要稍微分解一下print语句,请执行以下操作:

  • line.count('/')/个字符的数目
  • line.split('/')将字符串拆分为一个列表,例如['Parent', 'SiteF']
  • 可以将字符串乘以整数。' ' * 2 == ' '
  • [-1]选择列表的最后一个元素
  • 您可以将两个字符串与+一起添加'foo' + 'bar' == 'foobar'

(编辑)我在查看您的原始问题时注意到,您开始使用的输入实际上并没有单独包含Parent的条目,但您希望它出现在输出中。当然,只需抓取单个顶级根文件夹并将其添加到其中是很容易的,但是如果在树的任意深度的数据中存在其他漏洞呢?因此,我在添加一个集合理解时很开心,它将浏览路径列表,并通过从子文件夹中提取父文件夹的名称来“填充”任何丢失的父文件夹

for path in sorted(list(
    {
        '/'.join(path.split('/')[:i])
        for i in range(1, len(path.split('/')))
        for path in info
    } | set(info)
)):
    print('   ' * path.count('/') + path.split('/')[-1])

玩得开心

如注释中所述,如果用分隔符分割每一行,则得到的计数会随着路径深度的增加而增加。使用该数字重复“间隔符”字符,然后打印结果

sites = ['Parent/SiteA',
'Parent/SiteB',
'Parent/SiteC',
'Parent/SiteD',
'Parent/SiteD/xyz',
'Parent/SiteE',
'Parent/SiteD/xyz/Site8',
'Parent/SiteE/def',
'Parent/SiteF/Site3',
'Parent/SiteF',
'Parent/SiteF/Site4',
'Parent/SiteF/Site5']


spacer = ' '                                 # use whatever you need for spacer
for site in sorted(sites):
    prepend = len(line.split('/')) * spacer  # count how many items, and repeat the spacer
    item = line.split('/')[-1]               # the item we want to display is the last one
    print(prepend, item)

相关问题 更多 >