You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python列表切片修改疑问:新列表修改为何不影响原列表?

关于Python列表切片修改与浅拷贝的疑问解答

嘿,让我一步步拆解你的两个问题,结合你的代码和输出把事情说清楚:

问题1:修改Python列表的切片时会发生什么?

分两种核心情况:

  • 如果你直接对原列表的切片做赋值(比如A[1:3] = [10, 20]),这会直接修改原列表的对应位置——切片在这里相当于原列表的一个“视图”,赋值操作会替换原列表中该切片范围内的元素。
  • 但如果是把切片赋值给新变量(比如B = A[:]),这其实是创建了原列表的浅拷贝:新列表B和原列表A是两个独立的容器,但它们初始会共享对元素的引用。

问题2:为什么修改B的元素不影响A?

先看你的输出:一开始A和B的元素内存地址确实相同,这是因为浅拷贝复制的是元素的引用,不是元素本身。那为啥修改B后A没变化?核心原因是:你做的是重新赋值元素,而非修改元素本身的内容。

咱们掰碎了说:

  • 整数是Python里的不可变对象,你没法修改一个整数的内容(比如把0变成12345),所谓的“修改”其实是创建一个新的整数对象,然后让列表的对应位置指向这个新对象。
  • 你执行B[i] = 12345时,只是把B列表第i个位置的引用,从原来指向0/1/2等旧整数的地址,改成了指向新整数12345的地址。而A列表的第i个位置,依然牢牢指向原来的旧整数,所以A的内容完全不受影响。

如果你的列表里装的是可变对象(比如嵌套列表),情况就不一样了:比如A = [[1], [2]],B = A[:],这时候你修改B[0][0] = 10,A的内容也会变成[[10], [2]]——因为你修改的是可变对象内部的内容,而不是给列表元素重新赋值引用,这时候两个列表共享的可变对象被修改,自然都会体现变化。

再回头看你的代码:

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)

输出里初始元素地址相同,是因为B的每个元素都引用了A里的同一个整数。但赋值12345后,B的元素引用指向了新对象,A的还是旧的,所以结果才会A不变、B全变成12345。

你忽略的关键点就是:

  • A[:]是浅拷贝,两个列表独立,但共享不可变元素的引用;
  • 对不可变元素的“修改”本质是重新赋值引用,不会影响另一个列表;只有修改可变对象的内部内容时,才会让两个列表同步变化。

内容的提问来源于stack exchange,提问作者Alex Armbruster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 15:47:39