英文:
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'}}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论