问题描述
我有一些json数据,需要删除Python应用程序中某个键的每个实例。
例如,我想删除以下json数据中出现的“ badKey”。
{
"badKey": "0001","goodKey": "5432","interestingList": [
{
"badKey": "0001","goodKey": "0101"
}
],"coolList": {
"nestedDeeper": [
{
"keepsNesting": [
{
"badKey": "9999","otherKey": "7890"
}
],"hereToo": {
"badKey": "foobar","goodishKey": "baz"
}
}
]
}
}
它应该导致以下结果:
{
"goodKey": "5432","interestingList": [
{
"goodKey": "0101"
}
],"coolList": {
"nestedDeeper": [
{
"keepsNesting": [
{
"otherKey": "7890"
}
],"hereToo": {
"goodishKey": "baz"
}
}
]
}
}
有没有很好的pythonic方法来做到这一点?另外,输入和输出应为类似于以下的字节字符串(只要json可以接受,空格对我来说就没有关系):
b'{"badKey": "0001","interestingList": [{"badKey": "0001","goodKey": "0101" }],"coolList": {"nestedDeeper": [{"keepsNesting": [{"badKey": "9999","otherKey": "7890" }],"hereToo": {"badKey": "foobar","goodishKey": "baz"}}]}}'
我确定我可以提出一些正则表达式来搜索/替换输入字符串中的数据,但我认为要确保JSON语法完整无缺,所以我想将其加载到json模块中并在那里进行操作。
解决方法
一种解决方案是递归遍历数据并删除找到的密钥:
import json
json_string = b'{"badKey": "0001","goodKey": "5432","interestingList": [{"badKey": "0001","goodKey": "0101" }],"coolList": {"nestedDeeper": [{"keepsNesting": [{"badKey": "9999","otherKey": "7890" }],"hereToo": {"badKey": "foobar","goodishKey": "baz"}}]}}'
def remove_key(d):
if isinstance(d,dict):
if 'badKey' in d:
del d['badKey']
for v in d.values():
remove_key(v)
elif isinstance(d,list):
for v in d:
remove_key(v)
data = json.loads(json_string.decode('utf-8'))
remove_key(data)
# pretty print on screen:
print(json.dumps(data,indent=4))
# ...or convert to bytes:
print(json.dumps(data).encode('utf-8'))
打印:
{
"goodKey": "5432","interestingList": [
{
"goodKey": "0101"
}
],"coolList": {
"nestedDeeper": [
{
"keepsNesting": [
{
"otherKey": "7890"
}
],"hereToo": {
"goodishKey": "baz"
}
}
]
}
}
以及字节表示形式:
b'{"goodKey": "5432","interestingList": [{"goodKey": "0101"}],"coolList": {"nestedDeeper": [{"keepsNesting": [{"otherKey": "7890"}],"hereToo": {"goodishKey": "baz"}}]}}'
,
只需通过已加载的字典进行递归:
def deleteBadKey(badKey,dictionary):
for k,v in list(dictionary.items()):
if k == badKey:
del dictionary[k]
elif isinstance(v,dict):
deleteBadKey(badKey,v)
elif isinstance(v,list):
for d in v:
deleteBadKey(badKey,d)