2013-09-04 5 views
0

У меня есть кортеж, который выглядит следующим образом:Превращение плоского кортежа Python во вложенный словарь?

(
    ('Category 1', 40), 
    ('Category 1 | Sub-Category 1', 20), 
    ('Category 1 | Sub-Category 2', 20), 
    ('Category 1 | Sub-Category 2 | Sub-Sub-Category 1', 5), 
    ('Category 1 | Sub-Category 2 | Sub-Sub-Category 2', 15), 
    ('Category 2', 20), 
    ('Category 2 | Sub-Category 1', 15), 
    ('Category 2 | Sub-Category 2', 5) 
) 

Я хотел бы, чтобы превратить его в словарь, который выглядит следующим образом:

{ 
    'Category 1': { 
     'count': 40, 
     'children': { 
      'Sub-Category 1': {'count': 20, 'children': []}, 
      'Sub-Category 2': { 
       'count': 20, 
       'children': { 
        'Sub-Sub-Category 1': {'count': 5, 'children': []}, 
        'Sub-Sub-Category 2': {'count': 15, 'children': []} 
       } 
      } 
     } 
    }, 
    'Category 2': { 
     'count': 20, 
     'children': { 
      'Sub-Category 1': {'count': 15, 'children': []}, 
      'Sub-Category 2': {'count': 5, 'children': []}, 
     } 
    } 
} 

Есть произвольное число подкатегорий. Мне тяжело думать о питоническом способе этого. Какие-либо предложения?

EDIT: Если кто-то еще сталкивается с проблемой такого типа и хочет решения, вот что я (наконец) придумал. Я бы опубликовал в качестве ответа, но не могу, из-за закрытого вопроса (вздох).

from itertools import groupby 

def categoriesdict(value, depth=0): 
    categories = {} 
    for name, children in groupby(value, lambda c: c[0].split(' | ')[depth]): 
     # assumes that the first child is the group info 
     categories[name] = { 
      'count': children.next()[1], 
      'children': categoriesdict(children, depth + 1) 
     } 
    return categories 
+1

Вопросы, требующие кода, должны демонстрировать минимальное понимание решаемой проблемы. Включите попытки решения, почему они не работают и ожидаемые результаты. См. Также: Контрольный список вопросов переполнения стека – Marcin

+0

Но, я сделаю предложение: рекурсия. – Marcin

+0

Поскольку существует произвольное количество подкатегорий, я знаю, что рекурсия, скорее всего, будет частью решения. Мои попытки до сих пор не работали и не были полными. Я отправлю свои попытки немного, я извиняюсь за то, что не публиковал их по-настоящему, но действительно ли был необходим downvote? – Liam

ответ

2

Для каждого 2-кортежа, разделить первый кортеж [el.strip() for el in path.split('|')], а затем по этому пути, создавая словари и суб-словари.

Я отредактирую код в течение нескольких минут.

d = {'count': 0, 'children': {}} 
for (path, count) in els: 
    path = [el.strip() for el in path.split('|')] 
    here = d 
    for el in path: 
     print(el) 
     if el not in here['children']: 
      here['children'][el] = {'count': 0, 'children': {}} 
     here = here['children'][el] 
    here['count'] = count 
Смежные вопросы