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