Получение ключа уникальных значений во вложенном дикте в списках

python dictionary nested iteration

101 просмотра

2 ответа

У меня есть dict, который содержит элементы со следующей структурой

{'task0': {'id': 0, 'successor':[<other elements>]}

Каждый элемент содержит уникальный идентификатор и список преемников упомянутых элементов. Также может быть пустым, что означает, что этот элемент не имеет преемников.

пример

a = {'task0': {'node_id': 0, 'successor': [{'task1': {'node_id': 1, 'successor': [{'task2': {'node_id': 2, 'successor': [{'task4': {'node_id': 4, 'successor': []}}, {'task5': {'node_id': 5, 'successor': []}}]}},  {'task3': {'node_id': 3, 'successor': []}}]}}]}}

Что я хочу

def get_node_name_by_id(obj, id_search)

Пример: def get_node_name_by_id (a, 3) == 'task3'

def get_parent_id_by_child_id(obj, id_search)

Пример: def get_parent_id_by_child_id (a, 3) == 1

Что у меня пока

def get_node_name_by_id(obj, id_search):
    for k,v in obj.iteritems():
        if isinstance(v,dict):
            if v['node_id'] is id_search:
                return k
            elif v['successor']:
                    for e in v['successor']:
                        return get_node_name_by_id(e, id_search)

-> Проблема: если идентификатор, который я ищу, не находится на первом месте в списке, я получаю Noneв результате.

-> Для второй функции я понятия не имею, как ее реализовать

Вопрос

  • Как я могу исправить свои проблемы, соответственно, есть ли более разумный способ реализовать первую функцию?
  • Что было бы хорошей реализацией для второй функции?

Спасибо за любую помощь.

Автор: eljobso Источник Размещён: 08.11.2019 11:22

Ответы (2)


0 плюса

Очевидной проблемой, которую мы не видели ранее, было безусловное returnутверждение в вашем внутреннем цикле.

Вы должны возвращать что-то, только если это не так None, иначе другие элементы списка, кроме первого, игнорируются.

(обратите внимание , я изменил iteritemsна , itemsпотому что это питон 3 совместим и работает с последними версиями Python 2.7)

a = {'task0': {'node_id': 0, 'successor': [{'task1': {'node_id': 1, 'successor': [{'task2': {'node_id': 2, 'successor': [{'task4': {'node_id': 4, 'successor': []}}, {'task5': {'node_id': 5, 'successor': []}}]}},  {'task3': {'node_id': 3, 'successor': []}}]}}]}}

def get_node_name_by_id(obj, id_search):
    for k,v in obj.items():
        if isinstance(v,dict):
            if v['node_id'] is id_search:
                return k
            elif v['successor']:
                    for e in v['successor']:
                        r = get_node_name_by_id(e, id_search)
                        if r:
                            return r


print(get_node_name_by_id(a, 3))

выход:

task3
Автор: Jean-François Fabre Размещён: 20.08.2016 05:03

0 плюса

Решение

На основании комментария tobias_k я нашел более простой способ хранения информации. Поскольку каждый объект узла имеет уникальный идентификатор, достаточно хранить только эти идентификаторы. Индекс каждого подсписка является индексом узла, для которого определены преемники.

successor_list = [[successors_node0], [successors_node1], [successors_node2], ..., [successors_nodeN]]

С помощью идентификатора я могу получить доступ к объекту узла (все объекты узла хранятся в списке) для доступа к атрибутам объекта.

Автор: eljobso Размещён: 22.08.2016 10:40
Вопросы из категории :
32x32