[英]What is happening when you modify a slice of a python list
The following code creates a list, assigns a slice of the list to a new variable, and then modifies this slice using the new variable B
.以下代码创建一个列表,将列表的一个切片分配给一个新变量,然后使用新变量
B
修改该切片。 The memory addresses of the elements of A
and B
are the same, but modifying B does not affect A. What am I missing here? A
和B
的元素的内存地址是一样的,但是修改 B 不会影响 A。我在这里遗漏了什么?
def printAddresses(A):
for i in range(len(A)):
print(f"memory address of list element {i}: {hex(id(A[i]))}")
print("\n\n\n")
A = list(range(5))
B = A[:]
print("addresses of elements of A")
printAddresses(A)
print("addresses of elements of B")
printAddresses(B)
for i in range(len(B)):
B[i]=12345
print("A: ", A)
print("B: ", B)
Output:输出:
addresses of elements of A
memory address of list element 0: 0x10821e470
memory address of list element 1: 0x10821e490
memory address of list element 2: 0x10821e4b0
memory address of list element 3: 0x10821e4d0
memory address of list element 4: 0x10821e4f0
addresses of elements of B
memory address of list element 0: 0x10821e470
memory address of list element 1: 0x10821e490
memory address of list element 2: 0x10821e4b0
memory address of list element 3: 0x10821e4d0
memory address of list element 4: 0x10821e4f0
A: [0, 1, 2, 3, 4]
B: [12345, 12345, 12345, 12345, 12345]
The memory addresses of the data held by the lists are the same, since each list contains references to the same objects.列表保存的数据的内存地址是相同的,因为每个列表都包含对相同对象的引用。 A slice creates a shallow-copy, which means that the structure of the list is copied, but the objects it contains aren't .
切片创建浅拷贝,这意味着列表的结构被复制,但它包含的对象不是。
A
and B
both contain references to the same objects at the same time. A
和B
同时包含对相同对象的引用。
If you check the address of the structures themselves though, you'll see the difference:但是,如果您检查结构本身的地址,您会看到不同之处:
def printAddresses(A):
print(hex(id(A))) # Print list address
for i in range(len(A)):
print(f"memory address of list element {i}: {hex(id(A[i]))}")
print("\n\n\n")
Then, when run:然后,运行时:
addresses of elements of A
0x420cd88
memory address of list element 0: 0x63abf7a0
memory address of list element 1: 0x63abf7b0
memory address of list element 2: 0x63abf7c0
memory address of list element 3: 0x63abf7d0
memory address of list element 4: 0x63abf7e0
addresses of elements of B
0x195d0a8
memory address of list element 0: 0x63abf7a0
memory address of list element 1: 0x63abf7b0
memory address of list element 2: 0x63abf7c0
memory address of list element 3: 0x63abf7d0
memory address of list element 4: 0x63abf7e0
A: [0, 1, 2, 3, 4]
B: [12345, 12345, 12345, 12345, 12345]
Note how 0x420cd88
!= 0x195d0a8
.请注意如何
0x420cd88
!= 0x195d0a8
。 The objects held are literally the same, but the structures holding them are different.持有的对象实际上是相同的,但持有它们的结构不同。
I think a key here is that B[i]=12345
does not modify the object that was previously at i
.我认为这里的一个关键是
B[i]=12345
不会修改之前位于i
的对象。 B[0]=12345
removes the 0
from the list, then puts a 12345
in its place. B[0]=12345
从列表中删除0
,然后在其位置放置一个12345
。 That does not change the 0
.这不会改变
0
。
It's the same as how this:这与以下方式相同:
n = 0
list_a = [n]
list_b = [n] # Same object in both lists
list_a[0] = 9
print(list_a, list_b)
Prints [9] [0]
.打印
[9] [0]
。 This takes the 0
out of list_a
, and puts a 9
in its place.这
list_a
取出0
,并在其位置放置一个9
。 The 0
is not modified. 0
未修改。 Taking an orange of a box and putting an apple in its place does not modify the orange.取一个盒子里的橙子并在它的位置上放一个苹果不会改变橙子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.