万一你改变了visited
可变f
变量。如果current_label
您尝试将值重新分配给全局变量而不说明它是全局的。
从外部范围更改变量不需要将它们声明为全局变量,但是将值重新分配给全局变量需要声明它是全局变量 - 否则它被视为局部变量(如果在赋值之前引用,则会出现此类错误)。
让我们看一下代码:
1. def ts_r(n):
2. for nn in [v for v in g[n] if not visited[v]]:
3. visited[nn] = 1
4. ts_r(nn)
5. f[n] = current_label
6. current_label -= 1
在行5
中,您将全局变量值分配给f[n]
,但稍后,6
您尝试为该全局变量分配值。您没有告诉 Python 它是全局的,因此它假定它是本地的。但是如果它是本地的,你就不能更早地分配它。
你有两个选择:
(可能不是您要找的那个)将其用作本地:
def ts_r(n):
current_label = len(g) # initialize local variable
for nn in [v for v in g[n] if not visited[v]]:
visited[nn] = 1
ts_r(nn)
f[n] = current_label
current_label -= 1
告诉 Python 它是全局变量,并且您想更改全局变量的值:
def ts_r(n):
global current_label # current_label is now global
for nn in [v for v in g[n] if not visited[v]]:
visited[nn] = 1
ts_r(nn)
f[n] = current_label
current_label -= 1
编辑:
更新您的问题后,我看到了嵌套函数,而不是在全局范围内定义的函数。因此,解决方案global
不起作用。
在 Python 3.x 中你有nonlocal
关键字,但在 Python 2.x 的情况下你需要找到 walkaround。同样,您至少有两种可能性:
使用包含您要更改的不可变的可变变量(例如,其中包含一个整数的列表)。然后,当您仅引用(并更改)列表的第一个元素时。尝试一下。
另一种解决方案是为包装函数添加一个属性(函数也是可变的,因此可以更改它,但不会污染全局命名空间)。示例在这里:http: //ideone.com/7jGvM。在您的情况下,它可能如下所示:
def topological_sort(g):
visited = zeros((len(g)), dtype='int32')
f = zeros((len(g)), dtype='int32')
topological_sort.current_label = len(g) # [] so it is seen inside ts_r
def ts_r(n):
for nn in [v for v in g[n] if not visited[v]]:
visited[nn] = 1
ts_r(nn)
f[n] = topological_sort.current_label
topological_sort.current_label -= 1
for i in range(len(g)):
if not visited[i]:
ts_r(i)
return f