最佳方法删除字典中的嵌套键:

huangapple go评论68阅读模式
英文:

best way to remove nested key with in dictionary

问题

我有一个类似这样的字典:

acc = ["key1", "key_", "four"]

dict = {"key1": "something", "key_": "something2", "three": {"four": "remove this", "five": "dsadsdsas"}}

需要从JSON中删除acc变量中提到的所有特定键。

{key: value for key, value in dict.items() if key not in acc}

这不会删除"four"键。

所以我可以在这里做什么呢?

英文:

I have a dictionary something like this so

acc = ["key1", "key_", "four"]

dict = {"key1": "something", "key_": "something2", "three": {"four": "remove this", "five": "dsadsdsas"}}

Need to remove all this particular key from json which is mentioned in acc variable.

{key: value for key, value in dict.items() if key not in acc}

this doesn't remove the "four" key

So what can I do here?

答案1

得分: 4

无需翻译代码部分。以下是已翻译的内容:

问题出在它不像你期望的那样工作的原因是你的字典中的键是:key1key_threethree 不在 acc 中,因此保留了 three 的值。没有测试此值是否是字典,因此在筛选字典时没有使用。

因此,你需要使用递归来检查字典中的项是否本身是字典。如果是这种情况,也要筛选这个“嵌套字典”。

例如:

# 不要使用 dict,这是一个内置函数。
# https://docs.python.org/3/library/functions.html
d = {"key1": "something", "key_": "something2", "three": {"four": "remove this", "five": "dsadsdsas"}}

def filter_dict(d: dict, acc: list = ["key1", "key_", "four"]) -> dict:
    new_d = {}
    for key, value in d.items():
        if key in acc:
            continue
        if isinstance(value, dict):
            new_d[key] = filter_dict(value)
        else:
            new_d[key] = value
    return new_d

filter_dict(d)

>>> {'three': {'five': 'dsadsdsas'}}

当所有键都在 acc 中时,此示例将返回一个空字典。如何处理这种类型的字典取决于你,你可以更改此行以处理空字典:

new_d[key] = filter_dict(value)
英文:

The reason that it does not work like you would is that the keys in your dictionary are: key1, key_ and three. three is not in acc and the value of three is kept. That this value is a dictionary is not tested and therefore not used when you filter your dictionary.

Therefore you have to use recursion to check if the item in your dictionary is itself a dictionary. If that is the case, also filter this "dictionary inside a dictionary".

For example:

# do not use dict, this is a built-in function.
# https://docs.python.org/3/library/functions.html
d = {"key1": "something", "key_": "something2", "three": {"four": "remove this", "five": "dsadsdsas"}}

def filter_dict(d: dict, acc: list = ["key1", "key_", "four"]) -> dict:
    new_d = {}
    for key, value in d.items():
        if key in acc:
            continue
        if isinstance(value, dict):
            new_d[key] = filter_dict(value)
        else:
            new_d[key] = value
    return new_d

filter_dict(d)

>>> {'three': {'five': 'dsadsdsas'}}

This example will return an empty dictionary when all keys are inside acc. How to deal with those kind of dictionaries is up to you, you can change this line to deal with empty dictionaries:

new_d[key] = filter_dict(value)

答案2

得分: 0

import json

stop_k = ["key1", "key_", "four"]
d = {"key1": "something", "key_": "something2", "three": {"four": "remove this", "five": "dsadsdsas"}}
filtered = json.loads(json.dumps(d), object_pairs_hook=lambda pairs, stop_k=stop_k: \
    dict((k, v) for k, v in pairs if k not in stop_k))
{'three': {'five': 'dsadsdsas'}}
英文:

Simple trick with json.loads and its object_pairs_hook (used on decoding phase):

import json

stop_k = ["key1", "key_", "four"]
d = {"key1": "something", "key_": "something2", "three": {"four": "remove this", "five": "dsadsdsas"}}
filtered = json.loads(json.dumps(d), object_pairs_hook=lambda pairs, stop_k=stop_k: \
    dict((k,v) for k, v in pairs if k not in stop_k))

{'three': {'five': 'dsadsdsas'}}

huangapple
  • 本文由 发表于 2023年1月9日 16:16:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75054617.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定