Создайте вложенный список Python для использования в unordered_list Джанго - PullRequest
2 голосов
/ 20 февраля 2011

У меня есть модель Django с внешним ссылочным внешним ключом, поэтому моя модель (как класс в ее самой базовой форме) выглядит следующим образом:

class MyObj(object):
    def __init__(self, id, ttl, pid):
        self.id = id
        self.name = ttl
        self.parentid = pid

Таким образом, образец моих данных можетвыглядит так:

nodes = []
nodes.append(MyObj(1,'a',0))
nodes.append(MyObj(2,'b',0))
nodes.append(MyObj(3,'c',1))
nodes.append(MyObj(4,'d',1))
nodes.append(MyObj(5,'e',3))
nodes.append(MyObj(6,'f',2))

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

{'a': {'c': {'e': {}}, 'd': {}}, 'b': {'f': {}}}

используя Преобразование списка дерева в иерархию dict как руководство, но мне нужно это в форме, которую я могу использовать для фильтра unordered_list Django.

Итак, мой вопрос, как я могу получить из (любого) вложенного словаря ввложенный список / кортеж или прямо из исходных данных во вложенный список?Кажется, я не могу получить рекурсивную функцию для правильного вложения списков (так как в списке я не могу ссылаться на «поддеревья» по имени)

eval (string_rep_of_dictionary.replace (':', ',') .replace (' {',' ['). replace ('} ','] ')), кажется, вот-вот приведет меня туда, но это кажется ужасным решением?

Ответы [ 2 ]

1 голос
/ 20 февраля 2011

Попробуйте

lists = {}
for n in nodes:
    b = lists.setdefault(n.id, [])
    lists.setdefault(n.parentid, []).extend([n.name, b])
print lists[0]

или, используя collections.defaultdict

lists = collections.defaultdict(list)
for n in nodes:
    lists[n.parentid] += [n.name, lists[n.id]]
print lists[0]

оба из которых будут печатать

['a', ['c', ['e', []], 'd', []], 'b', ['f', []]]

Редактировать : Чтобы избавиться от пустых списков, повторите ите через узлы во второй раз:

for n in nodes:
    if not lists[n.id]:
        lists[n.parentid].remove(lists[n.id])
0 голосов
/ 20 февраля 2011
def nested_dict_to_list(d):
    result = []
    for key, value in d.iteritems():
        try:
            value = nested_dict_to_list(value)
        except AttributeError:
            pass
        result += [key, value]
    return result


test = {'a': {'c': {'e': {}}, 'd': {}}, 'b': {'f': {}}}
desired_result = ['a', ['c', ['e', []], 'd', []], 'b', ['f', []]]

nested_dict_to_list(test) == desired_result
# True
...