Python-将文件夹树转换为有组织的字典

Python-将文件夹树转换为有组织的字典,python,dictionary,Python,Dictionary,我有一个表示文件夹树的字典: 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" },

我有一个表示文件夹树的字典:

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...
文件夹中的文件夹的
:
#根目录中的文件夹名称前有空格
深度=文件夹['NAME']。拆分('')[0]。计数('-')
如果深度=0:
父项='0'
其他:
#对于每个以前的_文件夹:
previous_depth=previous_文件夹['NAME']。拆分('')[0]。计数('-'))
如果上一个深度<深度:
parent=pru文件夹['ID']
其他:
#继续找。。。

问题是用实际的工作代码填充注释行。如何从当前文件夹开始与列表上的每个上一个文件夹进行交互?还有我是如何循环的?

我认为诀窍是在当前父母、祖父母等的列表中跟踪祖先。你可以将他们从列表中删除,然后再回到基因库中。我有一些调试打印,你可以删除,但它帮助我看到了算法的进展情况。我创建了一个名为“”的虚拟根目录来处理顶级文件夹。您可以将其重命名为任何名称,即使您不希望它显示,也可以将其重命名为“”

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']))
文件夹=[{
“名称”:“文件夹1”,
“ID”:“869276”
}, {
“ID”:“869277”,
“名称”:”-子文件夹1”
}, {
“ID”:“869279”,
“名称”--子文件夹1
}, {
“名称”:“---子文件夹1 2”,
“ID”:“869285”
}, {
“名称”:“---子文件夹1 3”,
“ID”:“869286”
}, {
“名称”--子文件夹2“,
“ID”:“869280”
}, {
“ID”:“869281”,
“名称”:“文件夹2”
}, {
“ID”:“869282”,
“名称”:”-子文件夹2”
}, {
“名称”:“-子文件夹2 1”,
“ID”:“869283”
}, {
“名称”--子文件夹2 1“,
“ID”:“869284”
}]
#用于打印的文件夹索引(具有虚拟根目录)的id
文件夹\u by_id={folder['id']:文件夹中文件夹的文件夹}
文件夹_by_id['']={'NAME':'','id':-1}
#当前祖先堆栈
父母=['']
对于文件夹中的文件夹:
深度=文件夹['NAME'].split(“”)[0]。计数('-')+1(带虚拟根目录)
打印('state','parents',[folders\u by\u id[\u id]for\u id in parents],'name',folders['name'],'depth',depth)
当深度{child}({c_id})')。格式(
padding=''*parent['NAME'].计数('-'),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)
声明父文件夹[{'ID':-1,'NAME':'''}]NAME文件夹1深度1
状态父项[{'ID':-1,'NAME':'''},{'ID':'869276','NAME':'文件夹1','PARENT':'''}]名称-子文件夹1深度2
声明父项[{'ID':-1,'NAME':''},{'ID':'869276','NAME':'Folder 1','PARENT':''},{'ID':'869277','NAME':'-子文件夹1','PARENT':'869276'}]名称--子文件夹1深度3
说明父项[{'ID':-1,'NAME':'''},{'ID':'869276','NAME':'Folder 1','PARENT':'''''''.'''.'''.''.'''.''.'''.'''.'''.''.'''.''.'''.'''.''.''''.''.''''.'子文件夹1'.'.'.'.'''''.''''.'.'.'父项'.'.'.'.'.'.''
声明父文件夹[{'ID':-1,'NAME':'''},{'ID':'869276','NAME':'Folder 1','PARENT':''''''.'''.''.'''.'父文件夹['869277','PARENT':'.''.''.''.'''.''.'''.'''.'.''''.''.''''.''.'''.''''.-子文件夹1'''''.'.''''.''.'父文件夹'.'.'.'.'869279''.''''.''''''.''''''.''.''
拆卸869285
说明父项[{'ID':-1,'NAME':'''},{'ID':'869276','NAME':'Folder 1','PARENT':''''''.'''.''.''.''.'父项:'869279','NAME':'子文件夹1','PARENT':'869277'},{'ID':'869286','NAME':'.--子文件夹13','PARENT':'869279'.'''.'子文件夹2深度3
拆卸869286
拆卸869279
说明父项[{'ID':-1,'NAME':'''},{'ID':'869276','NAME':'Folder 1','PARENT':'''''''.'''.''.''.''.'''.''.'''.'''.'''.''.'''.'.'''.'''.''.'''''.''.'''.'子文件夹1','.'.''.''''.'''.'父项'.'.'.'.'.'.'.'
拆卸869280
拆卸869277
拆卸869276
声明父项[{'ID':-1,'NAME':'''},{'ID':'869281','NAME':'Folder 2','PARENT':'''}]名称-子文件夹2深度2
声明父项[{'ID':-1,'NAME':''},{'ID':'869281','NAME':'Folder 2','PARENT':''},{'ID':'869282','NAME':'-子文件夹2','PARENT':'869281'}]名称-子文件夹2 1深度2
拆卸869282
声明父文件夹[{'ID':-1,'NAME':''},{'ID':'869281','NAME':'Folder 2','PARENT':''},{'ID':'869283','NAME':'-子文件夹2 1','PARENT':'869281'}]名称--子文件夹2 1深度3
++++++++++++++++++++++++++++++给父母看+++++++++++++++++++++++++++++++
(-1)-->文件夹1(869276)
文件夹1(869276)-->-子文件夹1(869277)
-子文件夹1(869277)-->--子文件夹1(869279)
--子文件夹1(869279)-->——子文件夹12(869285)
--子文件夹1(869279)-->——子文件夹13(869286)
-子文件夹1(869277)-->--子文件夹2(869280)
(-1)-->文件夹2(869281)
文件夹2(869281)-->-子文件夹2(869282)
文件夹2(869281)-->-子文件夹2 1(869283)
-子文件夹21(869283)-->--子文件夹21(869284)

如果在dict中存储每个深度级别的父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

嗯,我开始觉得我不理解你。子文件夹1的父值应该是多少?869277,对不起,文件夹名称实际上是