Python二维列表赋值对列生效问题

Python二维列表赋值对列生效问题

问题背景

使用a = [[0]*6]*5新建了一个全0二维数组,在使用a[0][1] = 1对其中一个元素赋值时,发现对列1生效:

a = [[0]*6]*5
a[0][1] = 1
print(a)
# output:[[0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0]]

问题原因

https://www.geeksforgeeks.org/python-using-2d-arrays-lists-the-right-way/
使用列表乘法创建二维列表是一种浅拷贝方式,相乘时并没有生成新的整数对象,而是创建了新的变量,并指向原整数对象。也就是说,在初始化发生后,实际只有一个整数对象0产生。
初始化
当赋值arr[1][0]=1发生时,会创建一个新的整数对象1,此时里层1维列表的下标为0的arr[1][0]会指向新的整数对象1,而外层的列表仍然指向唯一的里层1维列表,所以外层列表的下标此刻指向的都是同一列表,下标并未生效。

赋值
所以会出现整列赋值被改变。
我们用查看内存地址的方法,可以看到a[0]a[1]地址相同:

a = [[0]*6]*5
a[0][1] = 1
print(a)
# id(): actual memory address
print(id(a[0]))
print(id(a[1]))
'''output
[[0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0]]
2536892439936
2536892439936
'''

解决方案

使用列表推导式:
https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions

rows, cols = (5, 5)
arr1 = [[0 for i in range(cols)] for j in range(rows)]
arr2 = [[0]*rows for _ in range(cols)]

浅拷贝和深拷贝

https://www.geeksforgeeks.org/copy-python-deep-copy-shallow-copy/
浅拷贝就是创建一个复杂变量,该变量的成员均为源对象所有子对象的引用
而深拷贝就是创建一个复杂变量,该变量的成员为源对象所有子对象的拷贝
深拷贝
浅拷贝

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值