Python: представление дерева структуры каталогов в виде списка списков - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть список каталогов, извлеченных из os.walk.Я удалил файлы, потому что они мне не нужны.

.
|____A
     |____G
     |____H
          |____K
          |____L
|____B
     |____I
     |____J
|____C
|____D
|____E
|____F
     |____M

Так это выглядит так:

['.', ['A', 'B', 'C', 'D', 'E', 'F']], ['A', ['G', 'H']], ['A\\G', []], ['A\\H', ['K', 'L']], ['A\\G\\K', []], ['A\\G\\L', []], ['B', ['I', 'J']], ['B\\I', []], ['B\\J', []], ['C', []], ['D', []], ['E', []], ['F', ['M']], ['F\\M', []]

Что мне действительно нужно, так это реальное представление древовидной структуры всписок вроде так:

['.', ['A' ['G', 'H' ['K', 'L']], ['B' ['I', 'J']], 'C', 'D', 'E', 'F' ['M']] 

ты;)

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

это не возвращает тип данных, который вы ищете, но вложенный словарь (так как для меня это более естественно, как древовидная структура):

from collections import defaultdict

lst = (['.', ['A', 'B', 'C', 'D', 'E', 'F']],
       ['A', ['G', 'H']], ['A\\G', []],
       ['A\\H', ['K', 'L']], ['A\\G\\K', []], ['A\\G\\L', []],
       ['B', ['I', 'J']], ['B\\I', []], ['B\\J', []], ['C', []],
       ['D', []], ['E', []], ['F', ['M']], ['F\\M', []])

def rec_dd():
    """"recursive default dict"""
    return defaultdict(rec_dd)

tree = rec_dd()
for here, dirs in lst:
    if not here.startswith('.'):
        cur_tree = tree['.']
    else:
        cur_tree = tree
    for key in here.split('\\'):
        cur_tree = cur_tree[key]

    for d in dirs:
        cur_tree[d] = rec_dd()

вы можете напечатать его следующим образом:

import json
print(json.dumps(tree, sort_keys=True, indent=4))

и результат:

{
    ".": {
        "A": {
            "G": {
                "K": {},
                "L": {}
            },
            "H": {
                "K": {},
                "L": {}
            }
        },
        "B": {
            "I": {},
            "J": {}
        },
        "C": {},
        "D": {},
        "E": {},
        "F": {
            "M": {}
        }
    }
}
0 голосов
/ 20 ноября 2018

Вы можете создать словарь из сплющенных значений, а затем использовать рекурсию:

import re
d = ['.', ['A', 'B', 'C', 'D', 'E', 'F']], ['A', ['G', 'H']], ['A\\G', []], ['A\\H', ['K', 'L']], ['A\\G\\K', []], ['A\\G\\L', []], ['B', ['I', 'J']], ['B\\I', []], ['B\\J', []], ['C', []], ['D', []], ['E', []], ['F', ['M']], ['F\\M', []]
new_d = {re.findall('.$', a)[0]:b for a, b in d}
def _tree(_start):
  if not new_d[_start]:
    return _start
  _c = [_tree(i) for i in new_d[_start]]
  return [_start, *(_c if any(not isinstance(i, str) for i in _c) else [_c])]

print(_tree('.'))

Вывод:

['.', ['A', 'G', ['H', ['K', 'L']]], ['B', ['I', 'J']], 'C', 'D', 'E', ['F', ['M']]]

Редактировать: версия Python2:

import re
d = ['.', ['A', 'B', 'C', 'D', 'E', 'F']], ['A', ['G', 'H']], ['A\\G', []], ['A\\H', ['K', 'L']], ['A\\G\\K', []], ['A\\G\\L', []], ['B', ['I', 'J']], ['B\\I', []], ['B\\J', []], ['C', []], ['D', []], ['E', []], ['F', ['M']], ['F\\M', []]
new_d = {re.findall('.$', a)[0]:b for a, b in d}
def _tree(_start):
  if not new_d[_start]:
    return _start
  _c = [_tree(i) for i in new_d[_start]]
  return [_start]+(_c if any(not isinstance(i, str) for i in _c) else [_c])

print(_tree('.'))
...