Python递归将元组列表排序为树结构

标签 python python-3.x sorting recursion tree-structure

我是编码新手,并且在尝试对元组列表进行递归排序时陷入困境。这是我的代码:

# table consists on [(code, parent), (code, parent), ...]
table = [('1', ''),
      ('1.1', '1'),
      ('2', ''),
      ('2.1','2'),
      ('2.1.1','2.1'),
      ('3',''),
      ('3.1','3'),
      ('4',''),
      ('4.1','4'),
      ('4.1.1','4.1'),
      ('4.1.2','4.1')]
content = {}
def rec(table, parent=None):
    while True:
        try:
            _code = table[0][0]
            _parent = table [0][1]
            if _parent == '':
                content[_code] = _parent
                return rec(table[1:])
            else:
                if _parent in content:
                    if content[_parent] == '':
                        content[_parent] = table[0]
                    else:
                        content[_parent] = content[_parent], table[0]
                    return rec(table[1:], parent=_parent)
                else:
                    content[_parent] = table[0]
                    return rec(table[1:], parent=_parent)           
        except IndexError:
            break
    return content

print(rec(table))

我得到的输出:

{'1': ('1.1', '1'), '2': ('2.1', '2'), '2.1': ('2.1.1', '2.1'), '3':('3.1', '3'), '4': ('4.1', '4'), '4.1': (('4.1.1', '4.1'), ('4.1.2','4.1'))}

但是期望的输出是:

{'1': ('1.1', '1'), '2': ('2.1', '2'), {'2.1': ('2.1.1', '2.1')}, '3': ('3.1','3'), '4': ('4.1', '4'), {'4.1': ('4.1.1', '4.1'), ('4.1.2', '4.1')}

我需要类似的东西:

{'node_id': '1', 'name':'somename', 'children': [{'node_id': '1.1' ,'name':'somename', 'children': [{'node_id': '1.1.1', 'name':'somename', 'children': [{'node_id': '1.1.1.1', 'name':'somename', 'children': []}]}, {'node_id': '1.1.2', 'name':'somename', 'children': []}, {'node_id': '1.1.3', 'name':'somename', 'children': []}]}, {'node_id': '1.2', 'name':'somename', 'children': []}]}

关于如何实现我的目标有什么想法吗?

最佳答案

要使输出成为嵌套字典树,它需要有一个常规结构,其中每个节点都是一个字典,其值代表子代字典,一直到叶节点,叶节点的子代有一个空字典。

这是一个构建树的简单循环:

table = [('1', ''),
      ('1.1', '1'),
      ('2', ''),
      ('2.1','2'),
      ('2.1.1','2.1'),
      ('3',''),
      ('3.1','3'),
      ('4',''),
      ('4.1','4'),
      ('4.1.1','4.1'),
      ('4.1.2','4.1')]

tree = { node:dict() for link in table for node in link }
for child,parent in table:
    tree[parent].update({child:tree[child]})

输出:

print(tree[""])  # "" is te root

{
 '1': { '1.1': {}},
 '2': {
        '2.1': { '2.1.1': {}}
      },
 '3': { '3.1': {}},
 '4': {
        '4.1': {
                 '4.1.1': {},
                 '4.1.2': {}
               }
      }
}

作为一个附带好处,此结构为您提供了树中所有节点的索引

对于属性字典(其中一个是子列表),可以使用相同的方法:

tree = { node:{"id":node,"children":[]} for link in table for node in link }
for child,parent in table:
    tree[parent]["children"].append(tree[child])

输出:

print(tree[""]["children"]) # children of root

[ { 'id': '1',
    'children': [ { 'id': '1.1', 'children': []} ]
  },
  { 'id': '2',
    'children': [
                  { 'id': '2.1',
                    'children': [ {'id': '2.1.1', 'children': []} ]
                  } 
                ]
  },
  { 'id': '3',
    'children': [ { 'id': '3.1','children': []} ]
  },
  { 'id': '4',
    'children': [
                  { 'id': '4.1',
                    'children': [
                                  { 'id': '4.1.1', 'children': []},
                                  { 'id': '4.1.2', 'children': []}
                                ]
                  }
                ]
  }
]

递归方法很好,但执行速度会慢得多,并且不会生成索引来通过节点的 ID 访问节点:

def tree(links,node=""):
    return {"id":node, "children":[tree(links,child) for child,parent in links if parent==node] }

root = tree(table)

关于Python递归将元组列表排序为树结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60694521/

相关文章:

python - matplotlib 中的 "Repel"注释?

python - 根据最近的值合并 Pandas 数据帧

python - Django REST FileUpload 序列化程序返回 {'file' : None}

python - 如何从核心转储分析内存使用情况?

python - 如何从列表中定位 python 小部件标签?

Django:如何在 sqlite3 数据库中添加/删除字段?

python - 是否可以在没有循环或附加模块的情况下从 BeautifulSoup 获取以下信息?

c# - 从字符串表示访问对象属性

Python:使用 lambda 以 str 格式对日期时间进行排序

swift - 在 Swift 中对 'grouped' Firebase 数据进行排序