Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 8, 2015 15:52:18

latino2003
Зарегистрирован: 2015-05-25
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

Рекурсивный поиск по вложенным словарям

Имеется словарь, который содержит значения ключей в виде:
1. словари
2. списки

info = [u'no', u'информацьион']
address = [u'Москва', u'Верхние поля', u'18а']
phones = []
vasya = {u'информация':info,
              u'адрес':address,
              u'телефоны':phones}
prot = []
base = [u'ground']
part = [1, 2, 3]
fedya = {u'протокол':prot,
              u'база':base,
              u'партия':part}
mila = [u'abc', u'безнадега', u'точка ру']
main_dict = {u'вася пупкин':vasya,
                   u'федя негров':fedya,
                   u'мила йовович':mila}

Задача:
пройтись рекурсивно по словарю, найти ключ равный match_key и вернуть его значения.

Что сделал:
def recursive(data, match_key):
    if type(data) == dict:
        for key, value in sorted(data.items()):
            if key == match_key:
                return key
            else:
                return recursive(value, match_key)

Но функция не работает:
print recursive(main_dict, u'телефоны') -> None

Прошу помощи!

Отредактировано latino2003 (Июнь 8, 2015 15:53:44)

Офлайн

#2 Июнь 8, 2015 16:15:28

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10010
Репутация: +  857  -
Профиль   Отправить e-mail  

Рекурсивный поиск по вложенным словарям

>>> info = [u'no', u'информацьион']
>>> address = [u'Москва', u'Верхние поля', u'18а']
>>> phones = ['ph1', 'ph2']
>>> vasya = {u'информация':info,
...          u'адрес':address,
...          u'телефоны':phones}
>>> 
>>> prot = []
>>> base = [u'ground']
>>> part = [1, 2, 3]
>>> fedya = {u'протокол':prot,
...          u'база':base,
...          u'партия':part}
>>> 
>>> mila = [u'abc', u'безнадега', u'точка ру']
>>> main_dict = {u'вася пупкин':vasya,
...              u'федя негров':fedya,
...              u'мила йовович':mila}
>>> 
>>> def find(dct, key):
...     assert isinstance(dct, dict)
...     if key in dct:
...         return dct[key]
...     else:
...         for i in dct.values():
...             if isinstance(i, dict):
...                 out = find(i, key)
...                 if out is not None:
...                     return out        
...         
... 
>>> find(main_dict, u'телефоны')
['ph1', 'ph2']
>>> find(main_dict, u'x')
>>>



Отредактировано py.user.next (Июнь 8, 2015 16:27:18)

Офлайн

#3 Июнь 9, 2015 10:17:36

latino2003
Зарегистрирован: 2015-05-25
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

Рекурсивный поиск по вложенным словарям

Спасибо!
Интересная конструкция assert. Если я правильно понял, это равносильно проверке if isinstance(dct, dict) или if type(dct) = dict?

Офлайн

#4 Июнь 9, 2015 10:52:12

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10010
Репутация: +  857  -
Профиль   Отправить e-mail  

Рекурсивный поиск по вложенным словарям

latino2003
это равносильно проверке if isinstance(dct, dict)
assert - это утверждение, он (оператор) ставится там, где не должна произойти обратная ситуация. Ставится он временно как напоминание о том, что нужно сделать проверку и породить исключение в случае ошибки.
(Если, например, будет подан список, то поиск может найти в нём ключ, хотя объект не подходит для поиска.)

Проверка через isinstance() от проверки через type() отличается тем, что isinstance() сработает также в случае, если тип порождён от dict.



Офлайн

#5 Июль 13, 2015 17:36:37

latino2003
Зарегистрирован: 2015-05-25
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

Рекурсивный поиск по вложенным словарям

Хм, а как вернуть значение из списка? Например, find(main_dict, u'Москва')
Если я правильно понимаю, то надо переделывать логику и делать на основе if type=dict … else?

Офлайн

#6 Июль 14, 2015 11:22:17

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10010
Репутация: +  857  -
Профиль   Отправить e-mail  

Рекурсивный поиск по вложенным словарям

latino2003
а как вернуть значение из списка?
Сначала нужно конкретно описать структуру: что может быть, чего не может быть.



Офлайн

#7 Июль 14, 2015 11:47:52

latino2003
Зарегистрирован: 2015-05-25
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

Рекурсивный поиск по вложенным словарям

py.user.next
Сначала нужно конкретно описать структуру: что может быть, чего не может быть.

Структура данных состоит из двух типов - словарь и список.
Значение словарей могут быть как списком, так и другим словарем. Списки всегда одномерные.

list1 = [] #пустой список
list2 = ['a', 'b', 'c']
list3 = ['d', 'e', 'f']
dict1 = {key:list1, key:list2}
dict2 = {key:dict1}
dict3 = {key:list3}
Словарь
… не может быть пустым.
… может содержать в качестве значений только список или словарь (в виде переменной)


Список
… может быть пустым
… не может быть многомерным



PS Для чего выбрана такая структура. Имеются данные, разбитые по категориям:


1. Основная категория 1
      1.1 Субкатегория 1
         1.1.1 Субсубкатегория 1
         1.1.2 Субсубкатегория 2
         1.1.3 Субсубкатегория 3
    1.2 Субкатегория 2
    1.3 Субкатегория 3
2. Основная категория 2
3. Основная категория 3
4. Основная категория 4


Количество подкатегорий может изменяться со временем как в большую, так и в меньшую стороны. Последняя подкатегория всегда является списком.

Отредактировано latino2003 (Июль 14, 2015 11:54:03)

Офлайн

#8 Июль 14, 2015 11:57:59

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Рекурсивный поиск по вложенным словарям

somedict[(key1, key2, key3)]
Не подойдёт?

Офлайн

#9 Июль 14, 2015 12:03:45

latino2003
Зарегистрирован: 2015-05-25
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

Рекурсивный поиск по вложенным словарям

Shaman
somedict[(key1, key2, key3)]
Не подойдёт?
Не совсем понял вашу мысль.

Офлайн

#10 Июль 14, 2015 12:16:14

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Рекурсивный поиск по вложенным словарям

Мысль: использовать сложные ключи в едином словаре. Судя по описанию структуры там нет словарей в списках и она вырождается в многомерный слорварь.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version