Уведомления

Группа в Telegram: @pythonsu

#1 Май 15, 2020 21:32:42

Sterh
Зарегистрирован: 2018-06-18
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

Вложенный словарь - найти элементы и сохранить путь

Приветствую!
Есть словарь неограниченной вложенности. Например:

 dd = {
     'raz':{1:'1', 2:'2'},
     'test':{1:'20'},
     'dva':{
         1:'30', 'test':{1:'11'}
     }
 }

Мне нужно найти все test и удалить их из словаря. При этом, если test является ключом, то удаляем все, что ниже по вложенности. Если конечным элементом, то удаляем конечный элемент.
Т.е., после удаления должно получится так:

  dd = {
     'raz':{1:'1', 2:'2'},
     'dva':{
         1:'30'
     }
 }

Рекурсивно обойти и найти сам элемент - не проблема. Проблема удалить. Если в рекурсии вкорячивать del, то получается, что изменяем итерируемый словарь.
Можно сделать копию словаря и удалять в ней, потом перевернуть.
Например:
 def searchKey(key, dikt):
    slov = dikt
    for k in slov: 
        if key == k:
            del slov[k]
        else:              
            if len(slov[k]) != 0: # Проверяем, есть ли вложенность, если да, то:
                new_slov = slov[k]
                searchKey(key, new_slov)
    dikt = slov

НО! Теперь самое главное! Мне нужна возможность “откатить” удаление. Т.е. вернуть удаленные элементы на прежнее место, через update к примеру. Для этого нужно как то сохранить пути, где эти элементы стояли в исходном словаре. Как это сделать?
Или просто - найти элемент и сохранить в переменную к нему путь?

Отредактировано Sterh (Май 15, 2020 21:33:27)

Офлайн

#2 Май 16, 2020 02:51:24

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

Вложенный словарь - найти элементы и сохранить путь

Sterh
Рекурсивно обойти и найти сам элемент - не проблема. Проблема удалить.
Так ты удаляй его ещё до входа в словарь. Операция in есть.

Sterh
Если в рекурсии вкорячивать del, то получается, что изменяем итерируемый словарь.
До входа в словарь применяешь in, по её результату применяешь del, потом заходишь в словарь рекурсивно. В нём уже всё будет удалено.

Sterh
НО! Теперь самое главное! Мне нужна возможность “откатить” удаление. Т.е. вернуть удаленные элементы на прежнее место
Значит, должен перед del применить deepcopy и сохранить удаляемое поддерево в какое-то место, где будет адрес в исходном дереве и само удалённое поддерево. Для восстановления нужна будет тоже функция.



Отредактировано py.user.next (Май 16, 2020 02:52:49)

Офлайн

#3 Май 16, 2020 12:08:54

Striver
От:
Зарегистрирован: 2006-10-26
Сообщения: 247
Репутация: +  22  -
Профиль   Отправить e-mail  

Вложенный словарь - найти элементы и сохранить путь

Рекурсивно обойти и найти сам элемент - не проблема. Проблема удалить. Если в рекурсии вкорячивать del, то получается, что изменяем итерируемый словарь.
Можно подойти к вопросу с другой стороны - проходя рекурсией, создавать новый словарь, в который копировать все пары ключ-значение, если это не test. Т.е. на самом деле вообще ничего не удалять.



Отредактировано Striver (Май 16, 2020 12:09:08)

Офлайн

#4 Май 16, 2020 12:40:32

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

Вложенный словарь - найти элементы и сохранить путь

Striver
создавать новый словарь, в который копировать все пары ключ-значение, если это не test. Т.е. на самом деле вообще ничего не удалять.
Это можно сделать, просто скопировав словарь и применив к копии функцию простого удаления с рекурсивным обходом.

Но вопрос копирования всего словаря не оптимален по операциям. Если там миллион элементов, а удаляемых ключей пара штук, а потом ещё такие словари поступают один за другим, то это всё копирование каждого словаря превращается в затратный процесс.



Отредактировано py.user.next (Май 16, 2020 12:41:12)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version