简体   繁体   English

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

[英]Python - Converting folder tree into organized dictionary

I have a dictionary representing a folder tree: 我有一本代表文件夹树的字典:

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"
}]

More clear representation: 更清晰的表示形式:

 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

I need to organize this dictionary into a new dictionary where every folder has the value for the parent folder, like 我需要将此字典组织成一个新的字典,其中每个文件夹都具有父文件夹的值,例如

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

So what I thought is to count the number of '-' before the folder name to keep track of folder depth: 所以我想在文件夹名称前计算“-”的数量以跟踪文件夹深度:

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...

The problem is filling the commented lines with actual working code. 问题是用实际的工作代码填充注释行。 How can I interact with each previous folder on the list starting from the current one? 从当前文件夹开始,如何与列表中的每个先前文件夹进行交互? And how I keep looping? 以及我如何继续循环播放?

I think the trick is to track ancestry in a list of current parent, grandparent, etc. You can bump them off the list to descend back into the gene pool. 我认为诀窍是在当前父母,祖父母等的列表中跟踪祖先。您可以将其从列表中移出,以下降到基因库中。 I've got some debug prints that you can remove but it helped me see how the algorithm was progressing. 我有一些调试打印可以删除,但是它帮助我了解了算法的进展情况。 I created a virtual root called "" to handle top level folders. 我创建了一个虚拟根目录“”来处理顶级文件夹。 You can rename that to anything, even "" if you don't want it to display. 您可以将其重命名为任何名称,即使您不想显示它也可以重命名为“”。

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']))

Output: 输出:

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)

If you store the parent ID of each depth level in a dict this can be done with just a few lines of code: 如果将每个深度级别的父级ID存储在dict中,则只需几行代码即可完成:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM