Python 切片显示相同的 id 位置
Python slice shows same id location
我是 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的价值?
当您执行 B = A[0:2]
时,最终实际上是在执行此操作,作为其中的一部分:B[0] = A[0]
。因此 A[0]
中的对象(整数 1
)与 B[0]
.
中的对象相同
当您设置 A[0] = 9
时,这些对象将不再相同。
另外,@ŁukaszRogalski 指出 CPython 缓存小整数。所以我们有 A[0] == 1 == B[0]
和 id(1) == id(1)
.
当A[0] == 9
,然后9 != 1 == B[0]
,id(9) != id(1)
。
试试这个:
id(1) == id(1) #True
原因是这些数字常量将在整个程序中重复使用。所以它就像给了一些内存来存储 1,然后在程序中提到 1 的任何地方,都会使用相同的内存,因此只会创建对该内存的引用。对象保持不变。
基本上,python 不会从列表中的每个项目创建新对象,只要您 copy/slice 一个它。
但是,虽然这不会对不可变对象造成任何麻烦,但您应该小心可变对象:
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
我是 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的价值?
当您执行 B = A[0:2]
时,最终实际上是在执行此操作,作为其中的一部分:B[0] = A[0]
。因此 A[0]
中的对象(整数 1
)与 B[0]
.
当您设置 A[0] = 9
时,这些对象将不再相同。
另外,@ŁukaszRogalski 指出 CPython 缓存小整数。所以我们有 A[0] == 1 == B[0]
和 id(1) == id(1)
.
当A[0] == 9
,然后9 != 1 == B[0]
,id(9) != id(1)
。
试试这个:
id(1) == id(1) #True
原因是这些数字常量将在整个程序中重复使用。所以它就像给了一些内存来存储 1,然后在程序中提到 1 的任何地方,都会使用相同的内存,因此只会创建对该内存的引用。对象保持不变。
基本上,python 不会从列表中的每个项目创建新对象,只要您 copy/slice 一个它。
但是,虽然这不会对不可变对象造成任何麻烦,但您应该小心可变对象:
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