Как преобразовать путь в словарь? Python
Самая банальная задача, но не понимаю как её решить. Если это возможно, то без стороних библиотек.
Суть такова, у меня есть список с путями, что-то типа:
products = [
"products",
"products.clothes",
"products.clothes.jeans",
"products.clothes.shirts",
"products.footwear",
"products.footwear.sneakers",
"products.footwear.boots",
"products.accessories"
]
Может быть любое количество элементов в списке. Путь так же может состоять из любого количества элементов.
Мне всё это дело нужно преобразовать в словарь и получить вот это:
elements = {
"products": {
"clothes": {
"jeans": None,
"shirts": None
},
"footwear": {
"sneakers": None,
"boots": None
},
"accessories": None
}
}
Как я могу это сделать?
Ответы (3 шт):
Автор решения: Zhihar
→ Ссылка
products = [
"products",
"products.clothes",
"products.clothes.jeans",
"products.clothes.shirts",
"products.footwear",
"products.footwear.sneakers",
"products.footwear.boots",
"products.accessories"
]
res = dict()
for object in products:
record = res
for element in object.split('.'):
if element not in record:
record.update({element: None})
else:
if record[element] is None:
record[element] = dict()
record = record[element]
print(res)
можно немного уменьшить код (НЕТ :)):
res = dict()
for object in products:
record = res
for element in object.split('.'):
record[element] = None if element not in record else dict() if record[element] is None else record[element]
record = record[element]
Автор решения: Богдан Соловьев
→ Ссылка
Может кому пригодится, тоже самое что и в ответе, но вложенность может быть любая.
def create_dict():
products = [
"products",
"products.clothes",
"products.clothes.jeans",
"products.clothes.shirts",
"products.footwear",
"products.footwear.sneakers",
"products.footwear.boots",
"products.accessories",
"products.accessories.1.2",
"products.accessories.1.2.3.4.5.clothes",
]
def deep_merge(source, destination):
"""
:param source - dict to merge
:param destination - destination dict, will be updated
:return updated destination
"""
for key, value in source.items():
if isinstance(value, dict):
# получаем или создаём узел n
n = destination.setdefault(key, {})
deep_merge(value, n)
else:
destination[key] = value
return destination
# тут будет результат
res = dict()
for e in products:
# получаем ключи из поля description в обратном порядке
keys = e.split('.')[::-1]
# узел будущего словаря
node = {}
# флаг который показывает, подставили ли value в конец словаря, елси да то последующие ключи подставляем
# выше по топологии
f = True
# идём по нашим ключам
# цель, собрать словарь node используя ключи полученные из элемента products
for k in keys:
if f:
# тут вместо None должен быть словарь, для работы рекурсии
node.update({k: {}})
f = False
else:
node = {k: node}
# мерджим полученный словарь с основным
deep_merge(node, res)
return res
Результат:
{
"products": {
"clothes": {
"jeans": {},
"shirts": {}
},
"footwear": {
"sneakers": {},
"boots": {}
},
"accessories": {
"1": {
"2": {
"3": {
"4": {
"5": {
"clothes": {}
}
}
}
}
}
}
}
}
Автор решения: vadim vaduxa
→ Ссылка
def setdefault(sline, dt):
for p in sline[:-1]:
dt = dt.setdefault(p, {})
dt.setdefault(sline[-1])
dt = {}
for line in sorted(products, key=lambda x: str.count(x, '.'), reverse=True):
setdefault(line.split('.'), dt)
print(dt)