Python:奇怪的列表行为

时间:2013-12-04 23:09:05

标签: python list

所以,我正在玩Python试图学习如何使用它,我发现了一些奇怪的东西。我的代码是:

list1 = range(0, 2)
list2 = range(2, 4)

comb = list1, list2

print comb
print list1

list1.append(list2)

print comb
print list1

输出是:

print comb   ---   ([0, 1], [2, 3])
print list1  ---   [0, 1]

print comb   ---   ([0, 1, [2, 3]], [2, 3])
print list1  ---   [0, 1, [2, 3]]

似乎正在发生的事情是我将两个列表组合在一起,这很好。但是当我将list2追加到list1并重新打印我的comb列表时,comb列表已使用新添加的list1更新。

我错过了什么?自comb追加以来,list1为什么没有重新计算时会发生变化?

5 个答案:

答案 0 :(得分:2)

comb包含引用list1list2本身,而不是它们的副本。此外,这意味着comb[0]实际上是list1和副作用。

以下是演示:

>>> list1 = range(0, 2)
>>> list2 = range(2, 4)
>>> comb = list1, list2
>>> id(list1)
28888960
>>> id(comb[0])
28888960
>>>

在上面的示例中,请注意list1comb[0]的ID是如何相同的。这告诉你的是它们都引用了内存中的同一个对象。因此,当您更新一个时,另一个也将更新。


要解决此问题,请comb包含list1list2副本,而不是参考:

>>> list1 = range(0, 2)
>>> list2 = range(2, 4)
>>> # [:] creates a shallow copy of the lists.
>>> comb = list1[:], list2[:]
>>> id(list1)
28930176
>>> id(comb[0])
28931696
>>>

如您所见,list1comb[0]的ID现在不同了。这意味着它们不再引用同一个对象。

答案 1 :(得分:2)

comb是一个元组,其中两个引用指向list1list2名称所引用的相同列表对象。

list2添加到list1后,您将该列表的另一个引用添加到list1。现在您有 3 对该列表对象的引用。一个位于list2,另一个位于comb[1],另一个位于list1[2]

每当您在Python中操作列表或字典或任何其他可变对象类型时,对该对象的所有引用都将反映这些更改,因为您只处理一个对象。

将图片对象作为气球,名称是标签,用线程绑定到气球上​​。线程是引用。你可以将多个标签绑在一个气球上,但你仍然只有一个气球,如果你弹出气球,所有的标签都会被绑在同一块无生命的橡胶上。

列表和元组只是带有编号标签的气球;这些标签与其他对象相关联。因此,comb是一个带有两个标签的气球,编号为0和1.这些标签与相同气球list1list2绑定< em>以及。

答案 2 :(得分:0)

comb引用保存到list1list2。因此,当您更新list1时,comb也会更新。

如果您希望comb保留list1list2而非参考的数据副本,请尝试:

comb = (list1[:], list2[:])

答案 3 :(得分:0)

comblist1list2组成。变异list1不会改变这一点,而comb似乎已经改变,但实际上它仍然完全相同。

答案 4 :(得分:0)

我的一位同事前几天有这个。这种效果源于你的

comb = list1, list2

您需要使用

comb = list(list1 + list2)

实际复制列表,参见http://www.precheur.org/python/copy_listhttp://od-eon.com/blogs/bogdan/python-assignment-value-or-reference/