Python中assignment与mutation行为疑问:列表a、b对c的影响差异
Python中赋值(Assignment)与可变对象修改(Mutation)的特性疑问
测试场景
初始代码执行:
a = [1, 1] b = [1, 1] c = a + [b] c >>> [1, 1, [1, 1]]
场景1:对b重新赋值
b = [2, 2] c >>> [1, 1, [1, 1]]
猜测原因:b指向了新的列表对象,而c仍指向b原本指向的对象。
场景2:对b的元素进行原地修改
b[0] = 2 c >>> [1, 1, [2, 1]]
猜测原因:修改的是b指向的原对象,而非让b指向新对象。
场景3:对a的元素进行原地修改
a[0] = 3 c >>> [1, 1, [1, 1]]
发现c未发生变化,与b的表现不同。
技术疑问
- 对上述b的行为理解是否正确?若不正确,该如何调整认知?
- 为何该逻辑不适用于a?推测是因为a并非c中的嵌套列表,但背后的原理是什么?
问题解答
1. 关于b的行为理解是否正确?
你的理解完全正确。
Python中变量本质是指向对象的引用:
- 初始时
b = [1,1],变量b引用了列表对象[1,1];执行c = a + [b]时,是把b当前引用的这个列表对象添加到c的末尾,因此c的第三个元素和b指向同一个对象。 - 执行
b = [2,2]属于重新赋值:变量b不再指向原[1,1]列表,转而指向新创建的[2,2]列表,但c的第三个元素仍指向原[1,1]对象,所以c无变化。 - 执行
b[0] = 2属于可变对象的原地修改:没有改变b的引用指向,只是直接修改了b所指向的原列表内容。由于c的第三个元素和b指向同一个对象,因此c会同步显示修改结果。
2. 为何修改a的元素不会影响c?
核心原因是:c = a + [b]执行时,a的元素是被复制到新列表中的,而非直接引用原a的列表对象。
具体逻辑:
- 列表的
+运算符会创建一个全新的列表对象,它会把a中的每个元素(这里是两个整数1)复制到新列表,再将[b]中的元素(即b引用的列表对象)添加到末尾。 - 因此
c的前两个元素是当初从a复制过来的旧值,c本身既不是a的引用,也没有嵌套a这个列表对象。 - 当执行
a[0] = 3时,只是修改了a所指向的列表对象的内容,但c的前两个元素和a当前的列表对象无关联,所以c不会变化。
如果要让c和a产生关联,可以直接将a作为元素嵌套进c,比如c = [a, b],此时修改a的元素就会影响c——因为c的第一个元素和a指向同一个列表对象。
内容的提问来源于stack exchange,提问作者user1748712
相关产品推荐
相关产品推荐

