将列表分配给Python中列表中的另一个列表

时间:2015-04-03 06:14:54

标签: python list reference

如果您有以下列表清单:

>> 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:可以在没有线性时间复制操作的情况下复制另一个列表吗?

3 个答案:

答案 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)