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

Posted

技术标签:

【中文标题】从嵌套字典中动态删除项目【英文标题】:Dynamically delete an item from a nested dictionary 【发布时间】:2015-01-26 12:32:18 【问题描述】:

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

字典可能如下所示:

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 中的相应项,通用代码会是什么样子?

【问题讨论】:

你确定你的key_list的顺序,如果你想删除相应的项目它不会引发KeyError No KeyError for me no. 两个问题可能会在我的脑海中具体化这个问题:1)每次都打算从字典中删除一个键/值对吗? 2) key_list 中键出现的顺序是否重要?我想第二个问题很像@Kasra 的问题。 在您的示例中,您是否打算将键视为 dict 中深度嵌套元素的路径,因此只删除叶子?或者您是否打算删除 key_list 中给出其键的每个元素? 一个额外的问题 - 不同的键可以在字典中多次出现(可以说是在不同的“级别”中)?例如 D = 'key1':'key1':'value1', 'key2':'value2' 【参考方案1】:

您可以使用 for 循环遍历 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'
>>>

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

【讨论】:

它似乎工作得很好!我没有意识到 sub 会影响 D,很好的解决方案。【参考方案2】:

您可以将嵌套字典视为具有多部分键的字典。如果你转换你的字典,那么你决定什么时候删除一个元素。如果密钥的一部分在密钥列表或任何其他条件中。考虑一下:

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'

【讨论】:

以上是关于从嵌套字典中动态删除项目的主要内容,如果未能解决你的问题,请参考以下文章

基于python中嵌套字典中的键删除项目

从嵌套字典中删除字典 [重复]

如何在迭代字典时从字典中删除项目?

如何在dynamoDB,嵌套字典或多个项目中构建数据?

从嵌套for循环中的指针集中删除项目

从 .NET 字典中删除与谓词匹配的多个项目的最佳方法?