2013-06-14 4 views
2

У меня есть Dict объект нечто подобное тому, как это,Python: дерево как реализации Dict структура данных

topo = { 
'name' : 'm0', 
'children' : [{ 
    'name' : 'm1', 
    'children' : [] 
}, { 
    'name' : 'm2', 
    'children' : [] 
}, { 
    'name' : 'm3', 
    'children' : [] 
}] 
} 

Теперь я хочу, чтобы вставить еще один объект ДИКТ скажем,

{ 
'name' : 'ABC', 
'children' : [] 
} 

, как ребенок из dict под названием «m2» в массиве детей m2.

Не могли бы вы предложить, как я должен это делать?

Должен ли я перейти к реализации отдельной структуры данных?

+1

В чем проблема? –

+1

Если вы хотите добавить к iten не по индексу, а по имени использовать dict или OrderedDict вместо списка для детей – oleg

ответ

3

Я хотел бы предложить вам сначала преобразовать его в структуру данных, как это:

topo = { 
    'm0' : { 
    'm1' : {}, 
    'm2' : {}, 
    'm3' : {}, 
    }, 
} 

То есть, вы сделали все значение ключа «имя» быть ключевым в словаре, и каждое значение ключ «children» будет значением для этого ключа и заменит его на словарь вместо списка.

Теперь вам не нужно заранее предполагать положение индекса, в котором находится м2. Вы должны знать, что m2 находится внутри m0, но тогда вы можете просто сказать

topo['m0']['m2']['ABC'] = {} 

Вы можете конвертировать между форматами с этим кодом:

def verbose_to_compact(verbose): 
    return { item['name']: verbose_to_compact(item['children']) for item in verbose } 

def compact_to_verbose(compact): 
    return [{'name':key, 'children':compact_to_verbose(value)} for key, value in compact] 

Позвоните им, как это

compact_topo = verbose_to_compact([topo]) # function expects list; make one-item list 
verbose_topo = compact_to_verbose(compact_topo)[0] # function returns list; extract the single item 

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

+0

'compact_to_verbose' не работает согласно требованию. –

+0

В чем проблема? – morningstar

+0

ValueError: требуется больше, чем 1 значение для распаковки –

0

Добавьте его в словаре, как обычно, с использованием .append():

topo['children'][1]['children'].append({'name' : 'ABC', 'children' : []}) 

topo Сейчас:

{ 
    "name": "m0", 
    "children": [ 
    { 
     "name": "m1", 
     "children": [] 
    }, 
    { 
     "name": "m2", 
     "children": [ 
     { 
      "name": "ABC", 
      "children": [] 
     } 
     ] 
    }, 
    { 
     "name": "m3", 
     "children": [] 
    } 
    ] 
} 
0
topo['children'].append({'name' : 'ABC', 
         'children' : [] 
        }) 
1
topo['children'][1]['children'].append({'name': 'ABC', 'children': []}) 

Это добавляет новый словарь под дети второго ребенка топо:

{'children': [{'children': [], 'name': 'm1'}, 
       {'children': [{'children': [], 'name': 'ABC'}], 'name': 'm2'}, 
       {'children': [], 'name': 'm2'}], 
'name': 'm0'} 

Но я бы не использовал dict и список встроенных объектов для такой задачи - я бы предпочел создать свои собственные объекты.

+0

Спасибо за ваше предложение. –

3

Ваша проблема - общая структура дерева, вы можете рассмотреть возможность использования http://pythonhosted.org/ete2/tutorial/tutorial_trees.html и заполнить каждый узел своим значением dict (не изобретать колесо).

+0

Вы можете использовать http://pythonhosted.org/ete2/tutorial/tutorial_trees.html#creating-trees-from-scratch для структуры своего дерева и использовать dict для сопоставления имени с его значением. –