2016-02-13 58 views
1

我的路徑和類似內容到一個列表:地圖路徑列表,文件結構

paths = [ 
    ("/test/file1.txt", "content1"), 
    ("/test/file2.txt", "content2"), 
    ("/file3.txt", "content3"), 
    ("/test1/test2/test3/file5.txt", "content5"), 
    ("/test2/file4.txt", "content4") 
] 

我將這個路徑列表轉換爲:

structure = { 
    "file3.txt": "content3" 
    "test": { 
     "file1.txt": "content1", 
     "file2.txt": "content2" 
    }, 
    "test2": { 
     "file4.txt": "content4" 
    } 
} 

有沒有簡單的解決辦法是問題?

回答

0

由於文件路徑可以是任意的深度,我們需要一種可擴展的。

這裏是一個遞歸方法 - 分裂遞歸直到我們正本清源/路徑:

import os 

paths = [ 
    ("/test/file1.txt", "content1"), 
    ("/test/file2.txt", "content2"), 
    ("/file3.txt", "content3"), 
    ("/test1/test2/test3/file5.txt", "content5"), 
    ("/test2/file4.txt", "content4") 
] 

def deepupdate(original, update): 
    for key, value in original.items(): 
     if key not in update: 
      update[key] = value 
     elif isinstance(value, dict): 
      deepupdate(value, update[key]) 
    return update 


def traverse(key, value): 
    directory = os.path.dirname(key) 
    filename = os.path.basename(key) 
    if directory == "/": 
     return value if isinstance(value, dict) else {filename: value} 
    else: 
     path, directory = os.path.split(directory) 
     return traverse(path, {directory: {filename: value}}) 


result = {} 
for key, value in paths: 
    result = deepupdate(result, traverse(key, value)) 

print(result) 

使用deepupdate() function這裏建議。

它打印:

{'file3.txt': 'content3', 
'test': {'file1.txt': 'content1', 'file2.txt': 'content2'}, 
'test1': {'test2': {'test3': {'file5.txt': 'content5'}}}, 
'test2': {'file4.txt': 'content4'}} 
0

嘗試使用遞歸性:

paths = [ 
    ("/test/file1.txt", "content1"), 
    ("/test/file2.txt", "content2"), 
    ("/file3.txt", "content3"), 
    ("/test2/file4.txt", "content4"), 
    ('/test1/test2/test3/file.txt', 'content'), 
    ('/test10/test20/test30/test40/file.txt', 'content100') 
] 

def create_structure(elems,count,mylen,p_1,var): 
    if mylen<=2: 
     var[elems[count]] = p_1 
     return 
    create_structure(elems,count+1,mylen-1,p_1,var.setdefault(elems[count],{})) 

structure = {} 
for p in paths: 
    elems = p[0].split('/') 
    create_structure(elems,1,len(elems),p[1],structure) 

print structure 
+0

很抱歉,但我的例子並不好。我的列表包含深度較大的路徑,如'('/test1/test2/test3/file.txt','content')'。 –

+0

@TomBarthe看我的編輯 –

0

我認爲.setdefault()是好的:

paths = [ 
    ("/test/file1.txt", "content1"), 
    ("/test/file2.txt", "content2"), 
    ("/file3.txt", "content3"), 
    ("/test2/file4.txt", "content4") 
] 

dirs = {} 

for p in paths: 
    current = dirs 
    ps = p[0].split('/') 
    for d in ps[:-1]: 
     if d: 
      current = current.setdefault(d, {}) 
    current[ps[-1]] = p[1] 

print(dirs) 
+0

任何深度沒有遞歸)) –