これまでのところ、どちらの回答も解決策を示唆していますが、これは投稿のポイントではありませんでした。違いは、リストに関しては、参照を操作していて、 のように「バインドされた」変数を操作していないことですsinglevalue
。l = l + [1]
たとえば、境界を変更しようとするとl
、同じエラーが発生します。これは、Python でのスコーピングの仕組みによるものです。
要するに:
singlevalue [local variable] = singlevalue [actually a global variable but access to locally stored variable] + 1 [constant]
singlevalue はローカルに保存されます。ここで、割り当てられていないため、まだ値を持たないローカルに保存された変数にアクセスしたいと考えています。グローバルに保存したい場合は、global
キーワードを使用する必要があります。
list[0] [slot in a referenced list] = list[0] [still same slot, which has a value already]+1
したがって、問題ありません。:)
より詳細に:
ここで Python のバイトコードを見て、読み込みの違いを確認できます。
>>> def m():
... y = 1
... def test():
... y = y + 1
... return y
... test()
>>> m()
UnboundLocalError: local variable 'y' referenced before assignment
>>> dis.dis(m)
[... cur here ... Inside of test()]
# <-- here the value of the constant is loaded from the local namespace
3 6 LOAD_CONST 2 (<code object test at 02A067B8, file "<pyshell#33>", line 3>)
9 MAKE_FUNCTION 0
12 STORE_FAST 1 (test)
[... cut here ...]
>>> def l():
... li = [1]
... def test():
... li[0] = li[0] + 1
... return li
... test()
>>> l()
[... cut here ... Inside of test()]
# <-- here a reference is loaded!
3 9 LOAD_CLOSURE 0 (li)
12 BUILD_TUPLE 1
15 LOAD_CONST 2 (<code object test at 02A06698, file "<pyshell#28>", line 3>)
18 MAKE_CLOSURE 0
21 STORE_FAST 0 (test)
[... cut here ...]
この投稿は長くなりすぎるため、上記のコマンドを実行して、http: //docs.python.org/2/library/dis.htmlを参照して違いを確認することをお勧めします。
ただし、物事の保存方法の主な違いは、最初のブロックで発生します。
2 0 LOAD_CONST 1 (1)
3 STORE_FAST 0 (y) # <- push loaded constant to stack
2 0 LOAD_CONST 1 (1)
3 BUILD_LIST 1
6 STORE_DEREF 0 (li) # <- stores the value in the list
ここを見てください!
これが違いを解消するのに役立つことを願っています。乾杯!