我有一个嵌套函数来实现如下算法:检查数组中循环的最长长度,输入数组中的值是跳转的下一个索引,获取循环的最大长度,否则只返回零。
但是如果我使用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)
答案 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循环中对访问和长度数组初始化的说法是正确的。