英文:
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
无需翻译代码部分。以下是已翻译的内容:
问题出在它不像你期望的那样工作的原因是你的字典中的键是:key1、key_ 和 three。three 不在 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'}}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论