Python多维数组初始化的两种方式和浅拷贝问题
来源:互联网 发布:mac看不到隐藏文件夹 编辑:程序博客网 时间:2024/05/18 15:05
Python提供了列表、元组、字典等数据结构,列表可以进行多层嵌套,形成“多维数组”。
最近在Python中使用列表嵌套定义数组时遇到了浅拷贝的问题,对多维数组初始化的2种方法进行了总结。
1.[0]*n复制列表
使用列表元素相乘的方式 [[[0]*a]*b]*n,初始化元素值为0的n维a*b数组。假设a=3,b=4,n=2,其初始化原理是将列表[0]复制3次成为[0,0,0],再将[0,0,0]列表对象的引用复制4次,得到初始化后的2维数组。
值得注意的是,把[0,0,0]*4这种复制形式是一种浅拷贝。对于list中的元素,浅拷贝就只会使用原始元素的引用(内存地址),也就是说A[0][1]、A[1][1]、A[2][1]、A[3][1]对应的是同一个内存地址,当对A中元素A[0][1]进行修改时,对象A中的A[i][1]的值都会发生变化。
# 初始化一维listA=[0]*4A[0, 0, 0, 0]# 改变其中一个元素的值A[0]=1A[1, 0, 0, 0] #不影响列表中其他元素的值# 初始化一个2维的4×3的数组,嵌套的listA=[[0]*3]*4A[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]#改变数组中的元素的值#嵌套列表初始化之后,内层列表元素值的改变,会影响整个列表对象A的值A[0][1]=1A[[0, 1, 0], [0, 1, 0], [0, 1, 0], [0, 1, 0]]A[1][1]=0A[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
2.通过循环赋初始值
通过for循环对列表进行赋值,逐个初始化元素为0。这种情况不会出现方法1中出现的浅拷贝问题。
B=[[0 for t in range(2)]for i in range(3)]B[[0, 0], [0, 0], [0, 0]]B[0][1]=1B[[0, 1], [0, 0], [0, 0]]
综上所述,通过循环赋初始值是一种比较推荐的初始化方法,不会因为对象引用的问题产生bug。
关于赋值、浅拷贝、深拷贝,可以用id()函数做实验,深入理解。id()函数可以返回对象的唯一编号,代表对象在python解释器中的内存地址。具体可参见这篇博客图解 Python 深拷贝和浅拷贝
# 方式1A=[0]*4print id(A)A=[[0]*3]*4print id(A)A[0][1]=1print id(A[0]),id(A[1])# 方式2B =[[0 for i in range(3)]for j in range(2)]print id(B[0]),id(B[1])
结果
# 方式1 列表内部的列表具有相同id,由此产生浅拷贝问题210971272 # id [0]*4138267400 # id [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]138267208 138267208 #id(A[0]),id(A[1])# 方式2 嵌套列表内部的列表具有不同的id210971720 210871240
阅读全文
0 0
- Python多维数组初始化的两种方式和浅拷贝问题
- 多维数组存储的两种方式
- python 多维数组的初始化生成
- 数组初始化的两种方式
- 数组的初始化两种方式?初始化常见错误
- 多维数组的初始化
- 多维数组的初始化
- [转]Python多维数组初始化
- 《python》---数组和多维数组的产生
- JavaScript初始化数组两种方式间的差异
- 【python学习笔记】多维数组初始化
- python 多维数组构建问题
- 多维数组的问题
- Python中字典的浅拷贝和深拷贝问题
- Python多维数组和矩阵
- Spring下的Bean初始化和销毁两种方式
- Spring下的Bean初始化和销毁两种方式
- Oracle拷贝数据的两种方式
- [杂题] Codeforces #121C. Lucky Permutation
- Guitar Pro 7中的谱子缩放设置介绍
- lua数据结构
- cassandra插入二进制大文件超时问题
- 疑问
- Python多维数组初始化的两种方式和浅拷贝问题
- 抓包工具-Fiddler
- Java初体验之springMvc(二) helloworld
- docker的疑问
- JAVA知识_14
- aop的使用
- QT打包程序——最简单的自带命令行
- dubbo + zookeeper 实例
- VMware安装centos7后无法上网解决方案