【问题标题】:Python - Converting folder tree into organized dictionaryPython - 将文件夹树转换为有组织的字典
【发布时间】:2017-03-24 03:11:48
【问题描述】:

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

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

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

【问题讨论】:

  • 嗯,我开始认为我不理解你。 子子文件夹 1 的 PARENT 值应该是多少?
  • 869277,抱歉文件夹名其实很混乱,看没有json结构的树更清晰

标签: python dictionary


【解决方案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)

【讨论】:

    【解决方案2】:

    如果您将每个深度级别的父 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
    

    【讨论】:

      猜你喜欢
      • 2019-10-03
      • 1970-01-01
      • 2017-07-21
      • 1970-01-01
      • 1970-01-01
      • 2020-04-14
      • 2020-12-16
      • 2023-03-15
      • 1970-01-01
      相关资源
      最近更新 更多