2017-03-23 25 views
0

我有代表一個文件夾樹的字典:Python的 - 將文件夾樹成有組織的字典

folders = [{ 
    "NAME": " Folder 1", 
    "ID": "869276" 
}, { 
    "ID": "869277", 
    "NAME": "- Sub-folder 1" 
}, { 
    "ID": "869279", 
    "NAME": "-- Sub-sub-folder 1" 
}, { 
    "NAME": "--- Sub-sub-folder 1 2", 
    "ID": "869285" 
}, { 
    "NAME": "--- Sub-sub-folder 1 3", 
    "ID": "869286" 
}, { 
    "NAME": "-- Sub-sub-folder 2", 
    "ID": "869280" 
}, { 
    "ID": "869281", 
    "NAME": " Folder 2" 
}, { 
    "ID": "869282", 
    "NAME": "- Sub-folder 2" 
}, { 
    "NAME": "- Sub-folder 2 1", 
    "ID": "869283" 
}, { 
    "NAME": "-- Sub-Sub-folder 2 1", 
    "ID": "869284" 
}] 

更明確表示:

Folder 1 
- Sub-folder 1 
-- Sub-sub-folder 1 
--- Sub-sub-folder 1 2 
--- Sub-sub-folder 1 3 
-- Sub-sub-folder 2 
Folder 2 
- Sub-folder 2 
- Sub-folder 2 1 
-- Sub-Sub-folder 2 1 

我需要組織本字典到一個新的字典,每一個文件夾具有父文件夾的值,如

[{ 
    "NAME": " Folder 1", 
    "ID": "869276", 
    "PARENT": "0" 
}, { 
    "ID": "869277", 
    "NAME": "- Sub-folder 1", 
    "PARENT": "869276" 
}, 
... 
] 

所以我認爲是數數在文件夾名稱前跟蹤文件夾深度的數量:

for folder in folders: 
    # Folders in root have a whitespace before the name 
    depth = folder['NAME'].split(' ')[0].count('-') 
    if depth == 0: 
     parent = '0' 
    else: 
     #for each previous_folder: 
      previous_depth = previous_folder['NAME'].split(' ')[0].count('-') 
      if previous_depth < depth: 
       parent = prvious_folder['ID'] 
      else: 
       #keep looking... 

問題是使用實際工作代碼填充註釋行。我怎樣才能從列表中的每個文件夾開始與當前文件夾進行交互?我如何保持循環?

+0

姆我開始覺得我不瞭解你。 PARENT值應該是多少**子子文件夾1 **? – PyNEwbie

+0

869277,對不起文件夾名稱其實很混亂,看看沒有json結構的樹更清晰 – Hyperion

回答

1

我想訣竅是跟蹤當前父母,祖父母等列表中的祖先。您可以將它們從列表中剔除,以便下載到基因庫中。我有一些可以刪除的調試打印,但它幫助我瞭解算法的進展情況。我創建了一個名爲「」的虛擬根來處理頂級文件夾。您可以將其重命名爲任何內容,即使是「」,如果您不希望它顯示。

folders = [{ 
    "NAME": " Folder 1", 
    "ID": "869276" 
}, { 
    "ID": "869277", 
    "NAME": "- Sub-folder 1" 
}, { 
    "ID": "869279", 
    "NAME": "-- Sub-sub-folder 1" 
}, { 
    "NAME": "--- Sub-sub-folder 1 2", 
    "ID": "869285" 
}, { 
    "NAME": "--- Sub-sub-folder 1 3", 
    "ID": "869286" 
}, { 
    "NAME": "-- Sub-sub-folder 2", 
    "ID": "869280" 
}, { 
    "ID": "869281", 
    "NAME": " Folder 2" 
}, { 
    "ID": "869282", 
    "NAME": "- Sub-folder 2" 
}, { 
    "NAME": "- Sub-folder 2 1", 
    "ID": "869283" 
}, { 
    "NAME": "-- Sub-Sub-folder 2 1", 
    "ID": "869284" 
}] 

# id to folder index (with virtual root) for printing 
folders_by_id = {folder['ID']:folder for folder in folders} 
folders_by_id['<root>'] = {'NAME':'<root>', 'ID':-1} 

# current ancestors stack 
parents = ['<root>'] 

for folder in folders: 
    depth = folder['NAME'].split(' ')[0].count('-') + 1 # w/ virtual root 
    print('state', 'parents', [folders_by_id[_id] for _id in parents], 'name', folder['NAME'], 'depth', depth) 
    while depth < len(parents): 
     old = parents.pop() 
     print('removing', old) 
    folder['PARENT'] = parents[-1] 
    parents.append(folder['ID']) 

print() 
print('++++++++++++++++++++++++++++++ showing parents +++++++++++++++++++++++++++++++') 
for folder in folders: 
    parent = folders_by_id[folder['PARENT']] 
    print('{padding}{parent} ({p_id}) --> {child} ({c_id})'.format(
     padding=' ' * parent['NAME'].count('-'), parent=parent['NAME'], 
     p_id= parent['ID'], child=folder['NAME'], c_id=folder['ID'])) 

輸出:

state parents [{'ID': -1, 'NAME': '<root>'}] name Folder 1 depth 1 
state parents [{'ID': -1, 'NAME': '<root>'}, {'ID': '869276', 'NAME': ' Folder 1', 'PARENT': '<root>'}] name - Sub-folder 1 depth 2 
state parents [{'ID': -1, 'NAME': '<root>'}, {'ID': '869276', 'NAME': ' Folder 1', 'PARENT': '<root>'}, {'ID': '869277', 'NAME': '- Sub-folder 1', 'PARENT': '869276'}] name -- Sub-sub-folder 1 depth 3 
state parents [{'ID': -1, 'NAME': '<root>'}, {'ID': '869276', 'NAME': ' Folder 1', 'PARENT': '<root>'}, {'ID': '869277', 'NAME': '- Sub-folder 1', 'PARENT': '869276'}, {'ID': '869279', 'NAME': '-- Sub-sub-folder 1', 'PARENT': '869277'}] name --- Sub-sub-folder 1 2 depth 4 
state parents [{'ID': -1, 'NAME': '<root>'}, {'ID': '869276', 'NAME': ' Folder 1', 'PARENT': '<root>'}, {'ID': '869277', 'NAME': '- Sub-folder 1', 'PARENT': '869276'}, {'ID': '869279', 'NAME': '-- Sub-sub-folder 1', 'PARENT': '869277'}, {'ID': '869285', 'NAME': '--- Sub-sub-folder 1 2', 'PARENT': '869279'}] name --- Sub-sub-folder 1 3 depth 4 
removing 869285 
state parents [{'ID': -1, 'NAME': '<root>'}, {'ID': '869276', 'NAME': ' Folder 1', 'PARENT': '<root>'}, {'ID': '869277', 'NAME': '- Sub-folder 1', 'PARENT': '869276'}, {'ID': '869279', 'NAME': '-- Sub-sub-folder 1', 'PARENT': '869277'}, {'ID': '869286', 'NAME': '--- Sub-sub-folder 1 3', 'PARENT': '869279'}] name -- Sub-sub-folder 2 depth 3 
removing 869286 
removing 869279 
state parents [{'ID': -1, 'NAME': '<root>'}, {'ID': '869276', 'NAME': ' Folder 1', 'PARENT': '<root>'}, {'ID': '869277', 'NAME': '- Sub-folder 1', 'PARENT': '869276'}, {'ID': '869280', 'NAME': '-- Sub-sub-folder 2', 'PARENT': '869277'}] name Folder 2 depth 1 
removing 869280 
removing 869277 
removing 869276 
state parents [{'ID': -1, 'NAME': '<root>'}, {'ID': '869281', 'NAME': ' Folder 2', 'PARENT': '<root>'}] name - Sub-folder 2 depth 2 
state parents [{'ID': -1, 'NAME': '<root>'}, {'ID': '869281', 'NAME': ' Folder 2', 'PARENT': '<root>'}, {'ID': '869282', 'NAME': '- Sub-folder 2', 'PARENT': '869281'}] name - Sub-folder 2 1 depth 2 
removing 869282 
state parents [{'ID': -1, 'NAME': '<root>'}, {'ID': '869281', 'NAME': ' Folder 2', 'PARENT': '<root>'}, {'ID': '869283', 'NAME': '- Sub-folder 2 1', 'PARENT': '869281'}] name -- Sub-Sub-folder 2 1 depth 3 

++++++++++++++++++++++++++++++ showing parents +++++++++++++++++++++++++++++++ 
<root> (-1) --> Folder 1 (869276) 
Folder 1 (869276) --> - Sub-folder 1 (869277) 
    - Sub-folder 1 (869277) --> -- Sub-sub-folder 1 (869279) 
     -- Sub-sub-folder 1 (869279) --> --- Sub-sub-folder 1 2 (869285) 
     -- Sub-sub-folder 1 (869279) --> --- Sub-sub-folder 1 3 (869286) 
    - Sub-folder 1 (869277) --> -- Sub-sub-folder 2 (869280) 
<root> (-1) --> Folder 2 (869281) 
Folder 2 (869281) --> - Sub-folder 2 (869282) 
Folder 2 (869281) --> - Sub-folder 2 1 (869283) 
    - Sub-folder 2 1 (869283) --> -- Sub-Sub-folder 2 1 (869284) 
0

如果每個深度級別的父ID存儲在一個字典這可以只用幾行代碼來完成:

def add_parent(folders): 
    parent = {0: '0'} 
    result = [] 
    for folder in folders: 
     depth = folder['NAME'].split(' ')[0].count('-') + 1 
     parent[depth] = folder['ID'] 
     folder['PARENT'] = parent[depth-1] 
     result.append(folder) 
    return result