Python列表乘法创建矩阵时引用行为不符预期的原因咨询
列表乘法的引用行为误区:为什么行元素没有全变成同一个值?
你的预期错误核心是混淆了引用指向和赋值操作对引用的修改逻辑,下面拆解代码里的引用关系和赋值过程:
代码里的引用位置
- 第一步
empty_row = [None] * len(A[0]):创建的列表中,所有元素都引用同一个None对象(因为None是Python单例,所以所有位置的id一致)。 - 第二步
empty_matrix = [empty_row] * len(A):empty_matrix的每一行都引用同一个empty_row列表对象,所以你打印行的id时全相同,这部分你的判断是对的。
为什么你的预期结果不对?
你执行empty_matrix[i][j] = i*10+j时,不是修改原来的None对象(None是不可变类型,根本没法修改),而是替换了empty_row列表中第j个位置的引用——把原来指向None的引用,改成指向新生成的整数i*10+j。
因为所有行都引用同一个empty_row,所以每次赋值都是在修改同一个列表的元素:
- i=0,j=0 → empty_row[0] = 0
- i=0,j=1 → empty_row[1] = 1
- i=1,j=0 → empty_row[0] = 10
- i=1,j=1 → empty_row[1] = 11
- i=2,j=0 → empty_row[0] = 20
- i=2,j=1 → empty_row[1] = 21
最后empty_row的内容被最后一次循环改成了[20,21],而所有行都是这个列表的引用,所以打印出来全是20,21。
你预期所有元素变成21,是误以为赋值操作在修改原None对象,但实际上None不可变,赋值是替换引用,且因为行共享同一个列表,后续赋值会覆盖之前的结果,而非让所有元素指向同一个值。
总结
- 存在引用的地方:
empty_row初始时所有元素指向同一个None;empty_matrix所有行指向同一个empty_row列表。 - 不存在引用的地方:赋值后,
empty_row的元素指向不同的整数对象(或被替换后的新引用);你的验证代码没有问题,是对引用和赋值的逻辑理解有误。
内容的提问来源于stack exchange,提问作者user778806
相关产品推荐
相关产品推荐

