Как превратить dict с абсолютными путями к файлу во вложенный Dict, похожий на структуру папок? - PullRequest
1 голос
/ 23 октября 2019

У меня есть что-то вроде:

source_dict = {
"/a": {"foo": "bar", "randomstuff": 3},
"/b/a": {"some": "thing", "abc": {"bx": 1}},
"/b/g/h/g": {"any": "value"}
}

Пути могут быть бесконечно глубокими, и они никогда не заканчиваются на / (> хранятся не пустые «папки»)

В течение нескольких часов япопытался получить source_dict для вложенного диктанта вроде:

final_dict = {"/": {
"a": {"foo": "bar", "randomstuff": 3},
"b": {"a": {"some": "thing", "abc": {"bx": 1}}, "g": {"h": {"g": {"any": "value"}}}}
}}

Значение не изменяется. Есть идеи?

1 Ответ

1 голос
/ 23 октября 2019

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

from itertools import groupby as gb
def group(d):
  new_d = [(a, list(b)) for a, b in gb(sorted(d, key=lambda x:x[0][0]), key=lambda x:x[0][0])]
  return {a:b[-1][-1] if not b[0][0][1:] else group([(c, k) for [_, *c], k in b]) for a, b in new_d}

source_dict = {"/a": {"foo": "bar", "randomstuff": 3}, "/b/a": {"some":"thing", "else":{"bx": 1}}, "/b/g/h/g": {"any": "value"}}
r = {'/':group([(list(filter(None, a.split('/'))), b) for a, b in source_dict.items()])}

Вывод:

{'/': {'a': {'foo': 'bar', 'randomstuff': 3}, 'b': {'a': {'some': 'thing', 'else': {'bx': 1}}, 'g': {'h': {'g': {'any': 'value'}}}}}}
...