Рекурсивно проходить по каталогам и возвращать вложенный список с подкаталогами и файлами в Python - PullRequest
0 голосов
/ 02 мая 2020

Я хотел бы рекурсивно пройти по каталогу в Python и получить вложенный список всех дочерних каталогов и файлов. Я нашел десятки решений для решения первой части (рекурсивный просмотр каталогов), но ни одно из них не позволяет мне получить вывод в нужном мне формате.

Нет ограничений / предпочтений, для которых библиотеки для использования. Я пытался с pathlib, но os.walk () тоже хорошо. Кроме того, не имеет рекурсивной функции. L oop в порядке.

У меня есть следующая структура:

root
├── file1.txt
├── file2.txt
├── sub1
│   ├── subfile1.txt
│   └── subsub
│       └── subsubfile1.txt
└── sub2

И мне нужен результат, чтобы быть вложенным списком, например, так:

[
  {
    'name': 'file1.txt'
  },
  {
    'name': 'file2.txt'
  },
  {
    'name': 'sub1',
    'children': [
      {
        'name': 'subfile1.txt'
      },
      {
        'name': 'subsub',
        'children': [
          {
            'name': 'subsubfile1.txt'
          }
        ]
      }
    ]
  },
  {
    'name': 'sub2'.
    'children': []
  }
]

Это то, как далеко я продвинулся, но это не дает правильных результатов:

from pathlib import Path
def walk(path: Path, result: list) -> list:
    for p in path.iterdir():
        if p.is_file():
            result.append({
                'name': p.name
            })
            yield result
        else:
            result.append({
                'name': p.name,
                'children': list(walk(p, result))
            })
walk(Path('root'), [])  # initial call

Помимо того, что этот код не работает, у меня также возникает проблема с рекурсивной коллекцией. Когда я пытаюсь его напечатать, он показывает:

'children': [ <Recursion on list with id=4598812496>,
                    <Recursion on list with id=4598812496>],
      'name': 'sub1'},

Можно ли получить этот объект рекурсии в виде списка?

Если кому-то интересно, зачем мне нужна эта структура, а не квартира список похож на тот, который возвращается pathlib.glob (), потому что этот список будет использоваться этим кодом на другой стороне моего API: https://vuetifyjs.com/en/components/treeview/#slots

1 Ответ

0 голосов
/ 02 мая 2020

Вы можете использовать os.listdir в рекурсии:

import os
def to_tree(s=os.getcwd()):
  return [{'name':i} if os.path.isfile(f'{s}/{i}') else 
              {'name':i, 'children':to_tree(f'{s}/{i}')} for i in os.listdir(s)]

При запуске вышеуказанной функции в файловой структуре, аналогичной приведенной в качестве примера, результат:

import json
print(json.dumps(to_tree(), indent=4))

Вывод:

[
  {
    "name": "file1.txt"
  },
  {
    "name": "file2.txt"
  },
  {
    "name": "sub1",
    "children": [
        {
            "name": "subfile1.txt"
        },
        {
            "name": "subsub",
            "children": [
                {
                    "name": "subsubfile1.txt"
                }
            ]
         }
      ]
  },
  {
    "name": "sub2",
    "children": []
  }
]
...