Python 递归创建树层次结构而不使用类/对象

Python 递归创建树层次结构而不使用类/对象,python,python-3.x,recursion,tree,hierarchy,Python,Python 3.x,Recursion,Tree,Hierarchy,在Python3中创建树层次结构时遇到问题。我希望不使用类也能做到这一点 我需要开始使用的数据不符合顺序,格式为['ID','Parent']: data=[['E1', 'C1'],['C1', 'P1'],['P1', 'R1'],['E2', 'C2'],['C2', 'P2'],['P2', 'R1'],['C3', 'P2'],['E3', 'C4'],['C4', 'P3'], ['P3', 'R2'],['C5', 'P3'],['E4', 'C6'],['C6', 'P4']

在Python3中创建树层次结构时遇到问题。我希望不使用类也能做到这一点

我需要开始使用的数据不符合顺序,格式为
['ID','Parent']

data=[['E1', 'C1'],['C1', 'P1'],['P1', 'R1'],['E2', 'C2'],['C2', 'P2'],['P2', 'R1'],['C3', 'P2'],['E3', 'C4'],['C4', 'P3'],
  ['P3', 'R2'],['C5', 'P3'],['E4', 'C6'],['C6', 'P4'], ['P4', 'R2'],['E5', 'C7'],['C7', 'P5'],['P5', 'R3'],['E6', 'C9'],['C9', 'P6'],['P6', 'R3'],
  ['C8', 'P6'],['E7', 'C10'],['C10', 'P7'],['P7', 'R4'],['C11', 'P7'],['E8', 'C12'],['C12', 'P8'],['P8', 'R4']]
我想在不使用类的情况下创建(Tree)dictionary变量,并最终得到如下结果:

Tree={'R1':{'P1':{},'P2':{}},'R2':{}} etc


显然R1和R2的子元素比这多,但可能这就是树结构的样子?

您可以简单地迭代每个
子元素
父元素
元组,创建字典,将子元素和父元素的id映射到包含这些元素的子元素的列表。我们一直这样做直到完成

roots = set()
mapping = {}
for child,parent in data:
    childitem = mapping.get(child,None)
    if childitem is None:
        childitem =  {}
        mapping[child] = childitem
    else:
        roots.discard(child)
    parentitem = mapping.get(parent,None)
    if parentitem is None:
        mapping[parent] = {child:childitem}
        roots.add(parent)
    else:
        parentitem[child] = childitem
既然我们已经这样做了,
roots
是树根的一组id:所以对于每个这样的元素,我们知道并没有作为父元素的id。对于
中的每个id,我们可以简单地从
映射
中获取,这是一个结构为
{'childid':child}
的字典,其中
childid
是id(这里是一个
字符串
),而
child
又是这种形式的字典

因此,您可以像这样打印它们:

for root in roots:
    print(mapping[root])
因此,在您的案例中,
树是:

tree = { id : mapping[id] for id in roots }
对于示例
数据
,它会生成:

>>> tree
{'R1': {'P1': {'C1': {'E1': {}}}, 'P2': {'C2': {'E2': {}}, 'C3': {}}}, 'R2': {'P4': {'C6': {'E4': {}}}, 'P3': {'C5': {}, 'C4': {'E3': {}}}}, 'R3': {'P6': {'C8': {}, 'C9': {'E6': {}}}, 'P5': {'C7': {'E5': {}}}}, 'R4': {'P8': {'C12': {'E8': {}}}, 'P7': {'C11': {}, 'C10': {'E7': {}}}}}

是否知道数据中元素的显示顺序?您知道不能对dict中的不同元素使用同一个键,对吗?;)Python字典必须具有唯一的键。如果您尝试定义类似于
{ID':1,'ID':2}
,您将得到
{ID':2}
因为第二个
'ID'
将覆盖第一个。不确定您对类有什么影响,因为这就是
dict
的含义,创建一个
dict
子类非常容易,它将使您想做的事情变得非常简单。请看我已经编辑了问题以提供一些示例数据,这不是为了开始感谢您的输入,但是输出树似乎不完整,例如P4应该有子C6,并且缺少C9之类的ID,在fact@new_to_coding你说得对。我找到了窃听器。现在应该可以了。这是正确的,非常感谢您的帮助@mapping dict正在自动更新,您能告诉我它是如何完成的示例:data=[['B','A'],['C','B']]1st迭代:mapping={'B':{},'A':{'B':{}}}2rd迭代:parentitem={}在执行最后一行代码后,我希望parentitem只更改parentitem={'C':{}wiered behavious was映射也会自动更改,即使最后一行代码没有手动更新映射dict这是如何工作的?映射dict是如何自动更改的?mapping={'B':{'C':{},'A':{'B':{'C':{}},'C':{}@star:您可以查看
以获得根父级,因此最后
只包含
A
。另一个不是自动更新的,它们只是对同一词典的两个引用,因此如果我们更新该词典,我们会在使用该词典的所有位置看到该更新。
>>> tree
{'R1': {'P1': {'C1': {'E1': {}}}, 'P2': {'C2': {'E2': {}}, 'C3': {}}}, 'R2': {'P4': {'C6': {'E4': {}}}, 'P3': {'C5': {}, 'C4': {'E3': {}}}}, 'R3': {'P6': {'C8': {}, 'C9': {'E6': {}}}, 'P5': {'C7': {'E5': {}}}}, 'R4': {'P8': {'C12': {'E8': {}}}, 'P7': {'C11': {}, 'C10': {'E7': {}}}}}