Python:嵌套函数外部作用域中的引用变量(非全局)

2024-04-24 10:40:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试递归一棵树,并跟踪遍历的路径,直到找到我要查找的元素为止。但是,我遇到两个问题:

  1. 虽然我当前的代码返回了正确的解决方案,但它有点粗糙。我必须将正在遍历的当前路径推送到final_path,然后返回final_path[0]。如果我只是试图设置final_path = path,其中{}是在外部范围内定义的,那么它就不起作用了。如何引用嵌套函数的外部作用域?

  2. 如果树中的值是而不是,我将以预先排序的方式遍历整个树。有没有什么方法可以构造代码,这样我就可以说“如果在遍历结束时,我们没有找到目标元素,那么只返回[]而不是完整路径”。我意识到我可以循环检查每个元素,但这似乎是非常多余的。

代码:

lftlft = {'val': 3, 'left': None, 'right': {'val': 100, 'left': None, 'right': None}}
rtrt = {'val': 5, 'left': None, 'right': None}
lft = {'val': 2, 'left': lftlft, 'right': {'val': 99, 'left': None, 'right': None}}
rt = {'val': 4, 'left': None, 'right': rtrt}
T = {'val': 1,'left': lft, 'right': rt}

def get_path(root, data, path):
    final_path = []

    def pre_order(tree, path):
        if tree is None:
            return

        path.append(tree['val'])

        if tree['val'] == data:
            final_path.append(path)
            return True

        return pre_order(tree['left'], path[:]) or pre_order(tree['right'], path[:])

    pre_order(root, [])
    print('finalpath', final_path)
    return final_path[0]

get_path(T, 99, [])

Tags: path代码路径rightnonetree元素return
3条回答

在python3.x中,只需使用关键字nonlocal。在

您可以在内部函数开头使用global:的地方使用它:

def get_path(root, data, path):
    final_path = ...

    def pre_order(tree, path):
        nonlocal final_path
        ...
    ...

    return final_path

即使在Python2.x中,只要引用一个变量,就会自动授予访问该变量的权限,但决不会授予写访问权限。请注意,如果引用的对象是可变对象,如列表或字典,则可以在内部函数中进一步修改它。在

在Python3.0中引入了nonlocal关键字,您可以对外部函数作用域中定义的变量有完全的写访问权限。]在

在python2.x中,让内部函数写入外部作用域列表中的固定元素可能是解决这个问题的最佳方法

我意识到我不必反复检查是否找到了它。不知道我为什么不早点加个旗子。在

rtrt = {'val': 5, 'left': None, 'right': None}
lft = {'val': 2, 'left': lftlft, 'right': {'val': 99, 'left': None, 'right': None}}
rt = {'val': 4, 'left': None, 'right': rtrt}
T = {'val': 1,'left': lft, 'right': rt}


def get_path(root, data, path):
    final_path = []
    found = False

    def pre_order(tree, path):
        if tree is None:
            return

        path.append(tree['val'])

        if tree['val'] == data:
            nonlocal final_path, found
            final_path = path
            found = True
            return found

        return pre_order(tree['left'], path[:]) or pre_order(tree['right'], path[:])

    pre_order(root, [])
    if not found:
        return []

    return final_path

get_path(T, 999, [])

我认为这是因为当你从get_path调用pre-order时,没有捕获返回值。在

下面的结果与您的代码示例的结果相同,如果我将值99更改为其他数字,则返回值None

lftlft = {'val': 3, 'left': None, 'right': {'val': 100, 'left': None, 'right': None}}
rtrt = {'val': 5, 'left': None, 'right': None}
lft = {'val': 2, 'left': lftlft, 'right': {'val': 99, 'left': None, 'right': None}}
rt = {'val': 4, 'left': None, 'right': rtrt}
T = {'val': 1,'left': lft, 'right': rt}

def get_path(root, data, path):

    def pre_order(tree, path):
        if tree is None:
            return

        path.append(tree['val'])

        if tree['val'] == data:
            return path
        return pre_order(tree['left'], path[:]) or pre_order(tree['right'], path[:])

    desired_result = pre_order(root, [])
    return desired_result

print (get_path(T, 99, []))

相关问题 更多 >