到目前为止,这两个答案都提出了一个解决方案,这不是帖子的重点。不同之处在于,关于列表,您使用的是引用,而不是像使用singlevalue
. 只要您尝试这样做:l = l + [1]
例如,您将尝试修改边界l
并得到相同的错误。那是因为 python 的作用域是如何工作的!
简而言之:
singlevalue [local variable] = singlevalue [actually a global variable but access to locally stored variable] + 1 [constant]
单值存储在本地。现在它想要访问本地存储的变量,该变量还没有值,因为它没有被赋值。如果要全局存储它,则需要使用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
看看这里!
我希望这有助于消除差异。干杯!