假设我想用全0来初始化一个2D Python列表,我会做类似的事情:
test = [[0.0] * 10] * 10
Run Code Online (Sandbox Code Playgroud)
然后我开始修改第一个列表中的值...
test[0][0] = 1.0
Run Code Online (Sandbox Code Playgroud)
但由于某种原因,这会影响ALL列表的第一项:
print test
[[1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]
Run Code Online (Sandbox Code Playgroud)
这是怎么回事?为什么它是内部列表的深层副本,而是外部列表的浅层副本?
这样做 [[0.0] * 10] * 10实际上创建相同的列表,从而改变一个会影响到所有的人的多个副本:
>>> test = [[0.0] * 10] * 10
>>> [id(x) for x in test] #see all IDs are same
[3065020524L, 3065020524L, 3065020524L, 3065020524L, 3065020524L, 3065020524L, 3065020524L, 3065020524L, 3065020524L, 3065020524L]
Run Code Online (Sandbox Code Playgroud)
试试这个:
>>> test = [[0.0]*10 for _ in xrange(10)]
>>> test[0][0] = 1.0
>>> test
[[1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]
Run Code Online (Sandbox Code Playgroud)
整数/浮点数是不可变的,而列表是可变的:
>>> x = y = []
>>> x is y # Both point to the same object
True
>>> x.append(1) # list.extend modifies a list in-place
>>> x,y # both references to [] can see the modification
([1], [1])
>>> x = y = 1
>>> x is y #both points to the same object
True
>>> x+=1 # only x gets modified, it now points to a new object 2
>>> x,y # y still points to the same object 1
(2, 1)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1158 次 |
| 最近记录: |