簡體   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