Python 从嵌套字典中动态删除项

Python 从嵌套字典中动态删除项,python,dictionary,nested,Python,Dictionary,Nested,我有一个嵌套字典,我希望能够删除其中的任意键 字典可以如下所示: D={'key1':{'key2':{'key3':'value3', 'key4':'value4'}, 'key5':'value5'}} key_list = ['key1', 'key2', 'key4'] 但它可以是任意大小的。问题是,这些密钥应该从“密钥列表”中提取,例如,如下所示: D={'key1':{'key2':{'key3':'value3', 'key4':'value4'}, 'key5':'valu

我有一个嵌套字典,我希望能够删除其中的任意键

字典可以如下所示:

D={'key1':{'key2':{'key3':'value3', 'key4':'value4'}, 'key5':'value5'}}
key_list = ['key1', 'key2', 'key4']
但它可以是任意大小的。问题是,这些密钥应该从“密钥列表”中提取,例如,如下所示:

D={'key1':{'key2':{'key3':'value3', 'key4':'value4'}, 'key5':'value5'}}
key_list = ['key1', 'key2', 'key4']
key\u list
可以是任意大小,并且可以包含字典的任何键

基于上述标准,我不能仅使用:

del D['key1']['key2']['key4']
因为我无法事先知道
key\u list
将包含哪些键


因此,基于
key\u list
的内容,删除字典
D
中相应项的通用代码会是什么样子?

您可以使用for循环遍历
key\u 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]]
因为
键\u列表[-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'}}}
>>>

除了解决方案是动态的(没有硬编码键)。

您可以将嵌套字典视为具有多部分键的字典。如果您转换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'}

你确定你的
按键列表的顺序吗?如果你想删除相应的项目,它不会引发
按键错误
!对我来说没有键错误。有两个问题可能会在我的脑海中结晶这个问题:1)每次都是为了从字典中删除一个键/值对吗?2) 按键列表中按键出现的顺序是否重要?我想第二个问题很像@Kasra所问的。在您的示例中,您是否打算将键视为dict中深度嵌套元素的路径,从而只删除叶?或者,您是否打算删除密钥列表中给出密钥的每个元素?还有一个问题-不同的密钥是否可以在字典中多次出现(可以说是在不同的“级别”中)?例如,D={'key1':{'key1':'value1','key2':'value2'}它似乎工作得很好!我不知道sub会影响D,很好的解决方案。