关于在递归中使用全局变量或局部变量

时间:2018-12-19 18:18:38

标签: python

最近,我在尝试构建Trie函数时遇到了一个微妙的问题:

def search(self, word):
    def dfs(node, word):
        if not word:
            if node.end:
                self.res = True
            return
        if word[0]!='.':
            node = node.next.get(word[0])
            if not node:
                return
            dfs(node, word[1:])
        else:
            for n in node.next.values():
                dfs(n, word[1:])

    curr = self.root
    self.res = False
    dfs(curr, word)
    return self.res

这有效。

但这不是:

def search(self, word):
    def dfs(node, word, res):
        if not word:
            if node.end:
                res = True
            return
        if word[0]!='.':
            node = node.next.get(word[0])
            if not node:
                return
            dfs(node, word[1:], res)
        else:
            for n in node.next.values():
                dfs(n, word[1:], res)

    curr = self.root
    res = False
    dfs(curr, word, res)
    return res

我不明白为什么后一种方法不起作用,该方法沿递归传递变量而不是使用全局变量。

1 个答案:

答案 0 :(得分:1)

问题与处理对象并将其传递给Python中的函数的方式有关。函数res中有一个新变量,初始化为调用该函数的对象。但是在函数内部分配res = True只是意味着res现在命名了一个不同的对象。它不会更改调用方范围内的对象。作为一个简单的示例,请想象以下代码:

def Test(result):
  if (something):
     result = True

Test(False) 

#what would I check to see if result changed?
#is the global False constant now equal to True?

我可以通过几种方法解决您的问题。

  1. 从函数返回resres = dfs(n, word, res)

  2. 传递一个数组,可以在函数内部修改其内容。 res = [True]将使res命名为另一个数组,但是res[0] = True会更改原始数组内的值。

喜欢这个。

res = [False]
dfs(n, word, res)
...
return res[0] 

3-使用nonlocal关键字在更高范围内使用变量:

def search(self, word):
    res = False
    def dfs(node, word):
        nonlocal res #this is the same object as the `res` in `search`
        if not word:
            if node.end:
                res = True #this will modify `res` as intended
        ... #rest of dfs function

    dfs(self.root, word)
    return res