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

Assigning a list to another list in a list of lists in Python

如果您有以下列表:

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

del A[0] 并不意味着删除 A[0] 元素的条目并且会在垃圾收集时被删除。它只是代表从 A[0] 变量中删除引用 link 到列表 ([2,3]).

Q1.1:为什么行为不同?人们可能希望这两个列表都被删除。

del A[0] 

没有释放 list [2,3] 的内存,也没有删除 list。它只是删除标签或将 A[0] 引用到列表 [2,3] .

Q1.2: 一个人是否可以在没有线性时间复制操作的情况下从另一个人那里复制一个列表?

A[0] = A[1][:]

例如

A = [[1], [2]]
A[0] = A[1][:]

>>id(A[0]),id(A[1])
(140215217604552, 140215217619208)

Q1.1

您必须区分对象和对象标识。标识只是对象存储单元的逻辑地址。当你在做A[0] = A[1]的时候,你实际上并没有复制对象,而是得到了对象的新标识。在 A[0] = A[1] 之后,你有两个 identities A[0]A[1] 到同一个对象,所以当你做 A[0].append(...)A[1].append(.),实际受影响的是同一个对象。

现在关于列表。 Python 中的列表不包含对象。他们持有对象的身份。您可以通过比较

来检查

sys.getsizeof([1])sys.getsizeof([1000000000000000000000000000000]),

尽管 10000000000000000000000000000000 明显比 1 重,但两者尺寸相同。

del 所做的是,它从列表中删除一个元素,它恰好是两个 identities 之一而不是对象,所以当你有一个包含同一对象的两个身份和 del 其中一个的列表,您仍然保留该对象和另一个身份 因为该对象仍被引用.

Q1.2

如果要复制,只需执行A[0] = A[1][:],这会将A[0]分配给一个切片。它应该更快。检查 this