用匹配的键递归替换字典值

swi*_*sly 4 python recursion dictionary

我正在尝试使用字典并找到所有匹配的键key并将它们的值替换为replace_value. 字典理论上可以无限深,因此必须递归完成。

我当前的解决方案正确替换了值,但引发了一个异常,说“调用 Python 对象时超出了最大递归深度”(更不用说它没有返回值的递归使用不当这一事实)。

def replace_item(obj, key, replace_value):
    """
    Replaces the dictionary value of key with replace_value in the obj dictionary.
    """
    if key in obj:
        obj[key] = replace_value

    for k, v in obj.items():
        if isinstance(v, dict):
            item = replace_item(v, key, replace_value)

            if item is not None:
                item = replace_value

     return obj
Run Code Online (Sandbox Code Playgroud)

它将执行的操作示例如下:

原始词典

person_dict = {
    "name": "Alex",
    "sex": "M",
    "title": "Engineer",
    "misc": {
        "mailbox": "3A",
        "work_type": "remote"
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我会调用replace_item(person_dict, "work_type", "office"),我最好将其更改为返回更新的字典 ( person_dict = replace_item(person_dict, "work_type", "office"))。

替换值字典

person_dict = {
    "name": "Alex",
    "sex": "M",
    "title": "Engineer"
    "misc": {
        "mailbox": "3A",
        "work_type": "office"
    }
}
Run Code Online (Sandbox Code Playgroud)

我该如何解决我的递归问题?先感谢您。

Far*_*Joe 7

你有一些奇怪的行为,你期待一个,return但你没有。此外,您的描述暗示它应该替换嵌套键,但是当顶级字典没有键但较低级别的字典有时,您将错过您的代码。我相信下面的代码完成了你所描述的:

def replace_item(obj, key, replace_value):
    for k, v in obj.items():
        if isinstance(v, dict):
            obj[k] = replace_item(v, key, replace_value)
    if key in obj:
        obj[key] = replace_value
    return obj
Run Code Online (Sandbox Code Playgroud)

编辑:正如@dashiell 所建议的,在递归搜索/替换之后移动顶级重新分配避免keyreplace_value.

  • 将替换放在递归下面也可能是一个好主意。例如,某人可以通过设置`key=some_key,replace_value={some_key:some_value}` 来获得最大递归深度错误 (2认同)