Разбор списка каталогов во вложенный словарь

#python #dictionary #directory-structure

Вопрос:

У меня есть следующие элементы в списке с форматом структуры каталогов.

 [  'fold/2021/',  'fold/2021/11/',  'fold/2021/11/01/',  'fold/2021/11/01/123.gz',  'fold/2021/11/01/345.gz',  'fold/2021/12/',  'fold/2021/12/02/',  'fold/2022/' ]  

Мне это нужно в следующей вложенной структуре словаря:

 {  "fold": {  "2021": {  "11": {  "01": {  "123.gz": None,  "345.gz": None  }  },  "12": {  "02": {}  }  },  "2022": {}  } }  

Я много пробовал с рекурсией и некоторыми другими методами, но я не получаю эту структуру.

Вот что я попробовал:

 def get_directory_structure(path):  global main_dict   local_dict = {}   a = path.rstrip('/').split('/')  local_dict.setdefault(a[0], {})   if len(a) gt; 1:  return_dict = get_directory_structure(path[path.find('/') 1:])    local_dict[a[0]] = return_dict   if a[0] == 'fold':  main_dict.update(**local_dict)    return local_dict  main_dict = {} for path in paths:  get_directory_structure(main_dict, path)  print(main_dict)  

Пожалуйста, помогите мне с этим. Спасибо

Примечание:- У меня нет папки на моем компьютере. У меня просто есть пункты в списке

Комментарии:

1. Должны ли они на самом деле быть "None" или None ? В любом случае, этот смешанный формат None dict и list может быть проблематичным , например, что, если в каталоге есть как файлы (которые будут списком), так и подкаталоги (которые будут диктовать)? Должен ли формат быть таким? Возможно, было бы лучше, как для создания, так и для последующего использования структуры, иметь все правила "02": {} для пустых каталогов и "123.gz": None файлов.


Ответ №1:

Вы можете попробовать так, не используя рекурсию, а используя * -распаковку, чтобы разделить элементы в файл (или '' ) и путь, ведущий к нему, и используя setdefault «развернуть» более глубокие уровни дикта, если они еще не существуют, и, наконец, добавить файл, если таковой имеется.

 res = {} for item in lst:  d = res  *path, last = item.split("/")  for p in path:  d = d.setdefault(p, {})  if last != "":  d[last] = None  

После res этого должен быть ваш желаемый результат:

 {'fold': {'2021': {'11': {'01': {'123.gz': None, '345.gz': None}}, '12': {'02': {}}}, '2022': {}}}  

Комментарии:

1. Это довольно умно-разделять путь и последнее (чтобы не иметь значения, которое я изо всех сил пытался понять), я вижу, как мы можем определить файл по косой черте в конце, 1