繁体   English   中英

如何将给定的列表列表转换为 Python 中的树结构?

[英]How can I convert a given list of lists to a tree structure in Python?

所以我基本上被困在这个问题上。 该问题为我们提供了一个零件库存清单,其中每个组件都由其他组件组成(以树关系的方式)。 例如,输入列表可以给出为

[["A",[2,"B"],[1,"C"]],
["B",[1,"D"],[1,"E"]],
["D",20.],
["E",10.]
["C",40.]]

,其中 A 由 2 个 B 和 1 个 C 组成,同样 B 由 1 个 D 和 1 个 E 组成。最后一个索引为浮点数的列表仅表示给定基本部分的单价。

问题是,我需要将此结构转换为可以写为的树表示;

[1,"A",[2,"B",[1,"D",20.],[1,"E",10.]], [1,"C",40.]]

我们只是将每个节点的子节点作为一个列表埋在嵌套列表结构中。 为了实现这一点,我尝试了一种递归迭代算法,但由于我们不知道一个节点有多少个子节点或树的深度是多少,所以我无法这样做。

你能推荐我一个解决这个问题的方法吗,在此先感谢。

PS:输入列表没有预定义的顺序,它的元素可以从树的底部到顶部放置或打乱。

如果您的输入结构保持不变,那么您可以尝试类似

e = [["A",[2,"B"],[1,"C"]],
["B",[1,"D"],[1,"E"]],
["D",20.],
["E",10.],
["C",40.]]

record = {}

for i in reversed(e):
    if(len(i) == 2):
        record[i[0]] = i[1]
    else:
        # there is children
        temp = []
        for j in i[1:]:
            if(isinstance(record[j[1]], list)):
                temp.append([*j, *record[j[1]]])
            else:
                temp.append([*j, record[j[1]]])
        record[i[0]] = temp

root = e[0][0]
print([1, root, *record[root]])  

output

[1, 'A', [2, 'B', [1, 'D', 20.0], [1, 'E', 10.0]], [1, 'C', 40.0]]

否则,您可以创建树结构并获取 output。

您可以利用列表是指针这一事实,通过在父列表中复制子列表引用来一次性执行链接:

def buildTree(data):
    index = { c[0]:c for c in data }  # used to access components by their id
    root  = index.copy()              # used to retain top level component(s)

    for component in data:
        if isinstance(component[1],float): continue   # no linking on leaf items
        for i,(_,prod) in enumerate(component[1:],1): # expand children
            component[i][1:] = index[prod]            # embed child in parent
            root.pop(prod)                            # remove child from root

    return [[1,*rv] for rv in root.values()] # output root item(s)

output:

data = [["A",[2,"B"],[1,"C"]],
        ["B",[1,"D"],[1,"E"]],
        ["D",20.0],
        ["E",10.0],
        ["C",40.0]]

print(*buildTree(data))
# [1, 'A', [2, 'B', [1, 'D', 20.0], [1, 'E', 10.0]], [1, 'C', 40.0]]

改变数据的顺序不会改变结果

data = [["D",20.0],
        ["E",10.0],
        ["B",[1,"D"],[1,"E"]],
        ["C",40.0],
        ["A",[2,"B"],[1,"C"]]]

print(*buildTree(data))
# [1, 'A', [2, 'B', [1, 'D', 20.0], [1, 'E', 10.0]], [1, 'C', 40.0]]

请注意,如果您的数据有多个根项,则 function 将 output 全部。 在这种情况下,只有一个,所以它只打印一个根

没有字典

如果您不允许使用字典,您仍然可以使用这种方法,但您必须对数据进行顺序搜索以通过其 id 查找产品:

def buildTree(data):
    roots  = data.copy() # used to retain top level component(s)
    for component in data:
        if isinstance(component[1],float): continue   # no linking on leaf items
        for i,(_,prod) in enumerate(component[1:],1): # expand children
            child = next(c for c in data if c[0]==prod) # find child with id
            component[i][1:] = child                  # embed child in parent
            roots.remove(child)                       # remove child from root
    return [[1,*rv] for rv in roots] # output root items

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM