max*_*ell 0 python memory copy
如果我做:
x = 1
y = [x,x,x,x]
y[1] = 2
print y
Run Code Online (Sandbox Code Playgroud)
我明白了:
[1,2,1,1]
Run Code Online (Sandbox Code Playgroud)
但如果我这样做:
x = [1,1]
y = [x,x,x,x]
y[1][0] = 2
print y
Run Code Online (Sandbox Code Playgroud)
我明白了:
[[2,1],[2,1],[2,1],[2,1]]
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释两者之间的细微差别吗?我的意思是,像Python如何分配内存,以便在第一种情况下,y的四个元素读取不同的内存位置,但在第二种情况下,y的四个元素读取相同的位置?
为什么Python的行为如此?当我使用Matlab时,不会发生这样的事情.
谢谢.
Python中的所有变量都包含引用(指针).即使是直接存储在C等其他语言中的变量中的简单类型(如整数)也会使用Python中的引用进行存储.为名称指定值会更改名称所指的内容(指向).准确理解何时发生这种情况对于理解Python的行为方式至关重要.
让我们开始:
a = 2 # points a to the integer object 2
a = 3 # points a to a different integer object, 3
b = [1, 2, 3] # points b to a new list object [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
下一个:
c = a # a and c now point to the same integer object, 3
d = b # b and d now point to the same list object, [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
到目前为止一切都那么好吧?现在你可以看到为什么它的工作方式如下:
d.append(4) # b and d still point to the same list object, which is
# now [1, 2, 3, 4]
print(b) # prints [1, 2, 3, 4] -- how could it not?
Run Code Online (Sandbox Code Playgroud)
事实上,无论对象的类型如何,一切都以相同的方式工作.只是某些类型你不能"就地"改变它们中的数字,字符串和元组:
a += 2 # a now points to the integer object 5, because you can't
# change 2 into 5 (integers are immutable)
print(c) # prints 3. c still points to 3, because you never told
# Python to make c point anywhere else!
Run Code Online (Sandbox Code Playgroud)
但:
b.append(5) # doesn't change what b points to, just changes the list
b += [6] # also (somewhat counterintuitively) doesn't change what b
# points to, even though it did with integers
print(d) # prints [1, 2, 3, 4, 5, 6] because b and d still point to
# the same list
Run Code Online (Sandbox Code Playgroud)
这种情况+=有点令人困惑,因为它与列表和整数的行为完全不同.但是,请记住,+=对象本身可以重新定义(以及大多数其他Python操作).在这种情况下,+=由__iadd__()附加到整数和列表类型的方法处理.在整数上,+=返回一个新对象,因为它必须是,整数是不可变的.在列表中,+=返回传递的相同对象被认为更有效,而不是复制.
总结一下:
+=)实际上不是赋值,而是方法调用,并不一定会改变变量(名称)引用的对象(指向),尽管它们可以