从嵌套字典/ json 中删除一个键

Faw*_*zan 2 python json python-3.x

我正在尝试使用 python 从 JSON 文件中删除一个元素。我已将字典转换为 python 字典,但到目前为止我一直失败。我正在使用的 JSON 文件上传到这里

如果键是'access_ip_v4'.

我不能使用 sed/grep 或任何其他正则表达式技术或字符串替换技术。在这方面,我有点被 Python 词典困住了。

这是我迄今为止的工作。

def dict_sweep(input_dic, k):
    for key in input_dic.keys():
        if key == k:
            print("DIRECT DELETE")
            del input_dic[key]
        elif type(input_dic[key]) is dict:
            print('DICT FOUND')
            input_dic[key] = dict_sweep(input_dic[key], k)
        elif isinstance(type(input_dic[key]), type([])):
            print("LIST FOUND")
            for i, v in enumerate(input_dic[key]):
                if isinstance(input_dic[key][i], dict):
                    input_dic[key][i] = dict_sweep(v, k)
    return input_dic
Run Code Online (Sandbox Code Playgroud)

我认为我的代码在遇到列表时会失败。从某种意义上说,失败,

clean_data = dict_sweep(data, 'access_ip_v4')
print(clean_data)
Run Code Online (Sandbox Code Playgroud)

将再次打印data而不是打印数据的清理版本。

我不太确定。我已阅读像其他一些问题,却是无益的。有人可以在这里给我指点吗?

Oli*_*çon 6

错误

你的错误来自于表达式isinstance(type(input_dic[key]), type([]))。您想检查是否input_dict[key]是列表,而不是type(input_dic[key])类型。

所以用这个替换最后一个elif语句。

elif isinstance(input_dic[key], list):
    print("LIST FOUND")
    ...
Run Code Online (Sandbox Code Playgroud)

更好的方法

虽然,不建议从您正在迭代的对象中删除。特别是,如果你使用的是 Python3,上面的代码会引发RuntimeError: dictionary changed size during iteration. 正确的方法是建立一个没有你想要删除的键的新字典。

def dict_sweep(input_dict, key):
    if isinstance(input_dict, dict):
        return {k: dict_sweep(v, key) for k, v in input_dict.items() if k != key}

    elif isinstance(input_dict, list):
        return [dict_sweep(element, key) for element in input_dict]

    else:
        return input_dict
Run Code Online (Sandbox Code Playgroud)

这是结果。

d = {'delete': 1, 'ok': [{'delete': 1, 'ok': 1}]}
new_d = dict_sweep(d, 'delete') # {'ok': [{'ok': 1}]}
Run Code Online (Sandbox Code Playgroud)