参数传递给Python中的嵌套函数

时间:2015-07-22 03:51:27

标签: python algorithm

我有一个嵌套函数来实现如下算法:检查数组中循环的最长长度,输入数组中的值是跳转的下一个索引,获取循环的最大长度,否则只返回零。

但是如果我使用result而不是result [],则会出现错误“UnboundLocalError:在赋值之前引用的局部变量'结果',它在函数dfs中找不到”result“参数,但是访问和长度可能是找。在我使用结果而不是结果之后,它可以工作。这是否意味着只有列表可以默认在嵌套函数中使用?

def max_length_loop(array):
    def dfs(index, len):
        if visited[index]:
            result[0] = max(result[0], len-length[index])
            return 
        visited[index] = True
        length[index] = len
        dfs(array[index], len + 1)

    if not array:
        return 0
    n = len(array)
    visited = [False for _ in xrange(n)]
    length = [0 for _ in xrange(n)]
    result = [0]
    for i in xrange(n):
        dfs(i, 0)
    return result[0] 


test = [1,2,3,4,0]
print max_length_loop(test)                      

2 个答案:

答案 0 :(得分:4)

当您在函数内部进行赋值时,解释器会假定左侧的名称是该函数中的本地引用,因此将该名称定义为该特定函数的本地名称(这也适用于嵌套函数)。因此,当您在实际分配变量result之前尝试访问该变量时,您会获得UnboundLocalError

显示此问题的最简单示例 -

>>> c = 10
>>> def a():
...     c = c + 10
...
>>> a()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in a
UnboundLocalError: local variable 'c' referenced before assignment

在你的情况下也会发生同样的事情。当您将行更改为result = <something>时,您实际上正在函数result内的dfs()变量上进行赋值,这会导致解释器将其视为局部变量,因此当您正在尝试访问result甚至在定义之前,你就会遇到问题。

您不应依赖此类嵌套作用域,并将所需的所有数据作为参数传递给函数。

另外,我注意到的另一件事是,你的逻辑有点不对,你应该在for循环中重新初始化visited数组和length数组,否则它将返回它找到的第一个循环最大长度循环。

示例 -

def max_length_loop(array):
    def dfs(index, len, result, visited, length):
        if visited[index]:
            result = max(result, len-length[index])
            return result
        visited[index] = True
        length[index] = len
        return dfs(array[index], len + 1, result, visited, length)
    if not array:
        return 0
    n = len(array)
    result = 0
    for i in range(n):
        visited = [False for _ in range(n)]
        length = [0 for _ in range(n)]
        result = max(dfs(i, 0, 0, visited, length), result)
    return result

test = [1,2,3,4,0]
max_length_loop(test)
>>> 5
test = [1,2,1,4,5,6,7,3]
max_length_loop(test)
>>> 5

答案 1 :(得分:0)

我认为问题出在这一行:

result[0] = max(result[0], len-length[index])

你想要的是做对吗?

result = max(result, len-length[index])

但是,第一次,你正在取结果和其他一些值的最大值,但之前没有使用过结果,那么max函数中会使用什么值?

如果您需要,可以将此行放在外部函数的顶部:    结果= 0

这将创建一个名为result的全局变量。

在dfs中,放

global result

所以你有这个(在Python 3中):

result = 0

def max_length_loop(array):

    def dfs(index, len):
        global result
        if visited[index]:
            result = max(result, len-length[index])
            return result
        visited[index] = True
        length[index] = len
        dfs(array[index], len + 1)

    if not array:
        return 0
    n = len(array)
    visited = [False for _ in range(n)]
    length = [0 for _ in range(n)]

    for i in range(n):
        visited = [False for _ in range(n)]
        length = [0 for _ in range(n)]
        dfs(i, 0)

    return result


test = [1,2,3,4,0]
print(max_length_loop(test))

Anand在for循环中对访问和长度数组初始化的说法是正确的。