Python切片显示相同的id位置

时间:2016-10-21 13:46:06

标签: python arrays python-2.7 slice

我是Python的初学者,所以请你解释一下为什么会出现以下情况。 请考虑以下代码:

>>> A = [1, 2, 3, 4]
>>> B = A[0:2]
>>> print id(A) == id(B)
False
>>> print id(A[0]) == id(B[0])
True                              #Why?
>>> A[0] = 9
>>> A
[9, 2, 3, 4]
>>> B 
[1, 2]
>>> print id(A[0]) == id(B[0])
False                             #Contradiction?

从上面的代码中可以看出,我将列表A切片并将其复制到B,但是,为什么print id(A[0]) == id(B[0])在第一个上评估True,但在我更改A中的任何一个时相反还是B的价值?

3 个答案:

答案 0 :(得分:2)

当你执行B = A[0:2]时,最终基本上会这样做,作为其中的一部分:B[0] = A[0]。因此1中的对象(整数A[0])与B[0]中的对象相同。

当你设置A[0] = 9时,那些对象就不一样了。

另外,正如@ŁukaszRogalski指出CPython缓存小整数。所以我们有A[0] == 1 == B[0]id(1) == id(1)

A[0] == 99 != 1 == B[0]id(9) != id(1)

答案 1 :(得分:2)

试试这个:

id(1) == id(1) #True

原因是这些数字常量将在整个程序中重复使用。因此它就像存储器1的存储器一样,然后在程序中提到1的任何地方,将使用相同的存储器,因此只会创建对该存储器的引用。对象保持不变。

答案 2 :(得分:1)

基本上,无论何时复制/切片,python都不会从列表中的每个项目创建新对象。

但是,虽然这不会对不可变对象造成任何麻烦,但是你应该小心使用可变对象:

In [22]: A = [[1, 2], 2, 3, 4]

In [23]: B = A[0:2]

In [24]: id(A[0]) == id(B[0])
Out[24]: True

In [27]: A[0][1] = 99

In [28]: B
Out[28]: [[1, 99], 2]

在这种情况下,您可以使用copy.deepcopy创建切片的新对象:

In [32]: import copy

In [33]: B = copy.deepcopy(A[0:2])

In [34]: A[0][1] = 5

In [35]: B
Out[35]: [[1, 99], 2]

In [36]: id(A[0]) == id(B[0])
Out[36]: False
           ^
        New Object