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にグローバルであるとは言わなかったので、ローカルであると想定します。ただし、ローカルの場合は、以前に割り当てることはできません。
2つの選択肢があります。
(おそらくあなたが探しているものではありません)ローカルとしてそれを使用してください:
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
キーワードがありますが、Python2.xの場合はウォークアラウンドを見つける必要があります。繰り返しますが、少なくとも2つの可能性があります。
変更する不変を囲む可変変数を使用します(たとえば、1つの整数を含むリスト)。次に、リストの最初の要素を参照(および変更)するだけです。それを試してみてください。
別の解決策は、ラッピング関数の属性を追加することです(関数も変更可能であるため、変更できますが、グローバル名前空間を汚染することはありません)。例はここにあります: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