2014-11-27 4 views
5

У меня есть вложенный словарь, и я хочу иметь возможность удалить из него произвольный ключ.Динамически удалять элемент из вложенного словаря

Словарь может выглядеть следующим образом:

D={'key1':{'key2':{'key3':'value3', 'key4':'value4'}, 'key5':'value5'}} 

Но это может быть произвольного размера. Проблема заключается в том, что ключи должны быть взяты из «списка ключей» ищет, например, так:

key_list = ['key1', 'key2', 'key4'] 

key_list может быть произвольного размера и иметь любой из кнопок словаря в нем.

Из приведенных выше критериев, я не могу просто использовать:

del D['key1']['key2']['key4'] 

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

Итак, как будет выглядеть общий код на основе содержимого key_list, удаляет соответствующий элемент в словаре D?

+0

Вы уверены, что заказали свой 'key_list', и если вы хотите удалить соответствующий элемент, он не будет поднимать' KeyError'! – Kasramvd

+0

No KeyError для меня нет. – PandaDeTapas

+0

Два вопроса, которые могут спровоцировать проблему в моем сознании: 1) Является ли намерение каждый раз удалять одну пару ключ/значение из словаря? 2) Значит ли последовательность, в которой ключи отображаются в ключевом списке? Я полагаю, что второй вопрос очень похож на то, что спрашивает @ Касра. – rchang

ответ

4

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

sub = D     # Start with the full dictionary 
for i in key_list[:-1]: 
    sub = sub[i]  # Move down a level 

В конце концов, sub будет словарь что вы хотите изменить. Все, что вам нужно сделать сейчас:

del sub[key_list[-1]] 

key_list[-1], поскольку это ключ, чтобы удалить.

Ниже демонстрация:

>>> D={'key1':{'key2':{'key3':'value3', 'key4':'value4'}, 'key5':'value5'}} 
>>> key_list = ['key1', 'key2', 'key4'] 
>>> sub = D 
>>> for i in key_list[:-1]: 
...  sub = sub[i] 
... 
>>> del sub[key_list[-1]] 
>>> D 
{'key1': {'key5': 'value5', 'key2': {'key3': 'value3'}}} 
>>> 

Как вы можете видеть, это эквивалентно:

>>> D={'key1':{'key2':{'key3':'value3', 'key4':'value4'}, 'key5':'value5'}} 
>>> del D['key1']['key2']['key4'] 
>>> D 
{'key1': {'key5': 'value5', 'key2': {'key3': 'value3'}}} 
>>> 

за исключением того, что решение динамических (не жестко закодированные ключи).

+0

Кажется, отлично работает! Я не понимал, что sub может повлиять на D, приятное решение. – PandaDeTapas

0

Вы можете думать о вложенных словарях, как о словаре с несколькими ключами. Если вы измените свой dict, тогда вы решите, когда удалить элемент. Если часть ключа находится в списке ключей или любых других критериях. Рассмотрите это:

D={'key1':{'key2':{'key3':'value3', 'key4':'value4', 'key7':{'key8':'value8'}}, 'key5':'value5'}, 'key6': 'value6'} 

def multipart_key(d): 
    dd = {} 
    for k in d: 
     if isinstance(d[k], dict): 
      inner = multipart_key(d[k]) 
      for kk in inner: 
       dd[k+chr(124)+kk] = inner[kk] 
     else: 
      dd[k] = d[k] 
    return dd 

key_list = ['key3', 'key7'] 

DD = multipart_key(D) 
newDD = DD.copy() 

for k in DD: 
    for kk in k.split(chr(124)): 
     if kk in key_list: 
      del newDD[k] 
      break 

print(DD) 
# {'key1|key2|key3': 'value3', 'key1|key5': 'value5', 'key6': 'value6', 'key1|key2|key7|key8': 'value8', 'key1|key2|key4': 'value4'} 

print(newDD) 
# {'key1|key5': 'value5', 'key6': 'value6', 'key1|key2|key4': 'value4'}