如果您有以下列表清单:
>> A = [[1], [2]]
然后说你通过以下方式将第二个列表分配到第一个列表:
>> A[0] = A[1]
您最终得到以下信息:
>> print A
[[2], [2]]
所以A [0]和A [1]现在指向同一个列表。如果您通过以下方式将元素附加到第一个元素:
>> A[0].append(3)
您将获得以下内容:
>> print A
[[2,3], [2,3]]
但是,如果您尝试删除第一个列表:
>> del A[0]
然后只删除一个列表,如下所示:
>> print A
[[1,2]]
Q1.1:为什么行为不同?有人可能会希望删除这两个列表。
显然,如果只想制作A [1]的副本,那么以下工作正常:
>> A = [[1], [2]]
>> A[0] = list(A[1])
>> print A
[[2], [2]]
>> A[0].append(3)
>> print A
[[2,3], [2]]
问题在于它的运行时间与要复制的列表的大小成线性关系,即A [1]。
Q1.2:可以在没有线性时间复制操作的情况下复制另一个列表吗?
答案 0 :(得分:1)
<强> Q1.1 即可。
您必须区分对象和对象标识。身份只是对象的内存单元的逻辑地址。当您执行A[0] = A[1]
时,您实际上并未复制该对象,但您会获得该对象的新标识。在A[0] = A[1]
之后,您有两个身份 A[0]
和A[1]
到同一个对象,因此当您执行A[0].append(...)
或A[1].append(.)
时,实际受影响的是同一个对象。
现在关于列表。 Python中的列表不包含对象。他们拥有对象的身份。您可以通过比较来检查
sys.getsizeof([1])
和sys.getsizeof([1000000000000000000000000000000])
,
两者的大小相同,但10000000000000000000000000000000
明显比1
重。
del
的作用是什么,它会从列表中删除一个元素,它恰好是两个标识之一,而不是对象,所以当你有一个包含两个的列表时同一个对象的身份和del
其中一个,您仍保留对象和另一个身份,因为该对象仍被引用。
<强> Q1.2 即可。
如果您想要复制,可以A[0] = A[1][:]
,A[0]
将{{1}}分配给切片。它应该更快。检查this。
答案 1 :(得分:0)
del A [0] 并不意味着删除A [0]元素的条目并且将在垃圾收集时删除。它只是代表从A [0]变量到列表([2,3])删除参考链接。
答案 2 :(得分:0)
Q1.1:为什么行为不同?有人可能会希望删除这两个列表。
del A[0]
不会释放list
[2,3]
的内存,也不会删除list
。它只是删除标记或引用A[0]
到列表[2,3]
。< / p>
Q1.2:可以在没有线性时间复制操作的情况下复制另一个列表吗?
A[0] = A[1][:]
例如
A = [[1], [2]]
A[0] = A[1][:]
>>id(A[0]),id(A[1])
(140215217604552, 140215217619208)