[英]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.