一、变量赋值:
1、变量的初始化

变量的每一次初始化,都开辟了一个新的空间,将新内容的地址赋值给变量(即变量的内存地址改变)。对于下图来说,我们重复的给str1赋值,其实在内存中的变化如下右图:

  

python 数字复制为变为固定长度的数组_存储空间

         

python 数字复制为变为固定长度的数组_赋值_02

  从上图我们可以看出,str1在重复的初始化过程中,是因为str1中存储的元素地址由'hello world'的地址变成了'new hello world'的。

2、列表变量的增删改

  

python 数字复制为变为固定长度的数组_数据结构与算法_03

         

python 数字复制为变为固定长度的数组_数据结构与算法_04

  当对列表中的元素进行一些增删改的操作的时候,是不会影响到lst1列表本身对于整个列表地址的,只会改变其内部元素的地址引用。可是当我们对于一个列表重新初始化(赋值)的时候,就给lst1这个变量重新赋予了一个地址,

覆盖了原本列表的地址,这个时候,lst1列表的内存id就发生了改变。上面这个道理用在所有复杂的数据类型中都是一样的。

3、变量赋值

(1)str的赋值

  

python 数字复制为变为固定长度的数组_存储空间_05

           

python 数字复制为变为固定长度的数组_python_06

  我们刚刚已经知道,str1的再次初始化(赋值)会导致内存地址的改变,从上图的结果我们可以看出修改了str1之后,被赋值的str2从内存地址到值都没有受到影响。

  看内存中的变化,起始的赋值操作让str1和str2变量都存储了‘hello world’所在的地址,重新对str1初始化,使str1中存储的地址发生了改变,指向了新建的值,此时str2变量存储的内存地址并未改变,所以不受影响。

(2)列表的赋值

  

python 数字复制为变为固定长度的数组_初始化_07

         

python 数字复制为变为固定长度的数组_初始化_08

  上图对列表的增加修改操作,没有改变列表的内存地址,lst1和lst2都发生了变化。

  对照内存图我们不难看出,在列表中添加新值时,列表中又多存储了一个新元素的地址,而列表本身的地址没有变化,所以lst1和lst2的id均没有改变并且都被添加了一个新的元素。

  总结:无论对于列表的复杂结构、还是对于字符串的结构,只要对变量做了一次初始化,就会开辟一个新的存储空间(列表的增删改不会开辟新的内存空间)。这样赋值后的那个变量str2,还是指向第一次指向的内存空间str1(不会指向第二次初始化的变量值,即新的str1)

 

二、拷贝copy

浅拷贝:不管多么复杂的数据结构,浅拷贝都只会copy一层;最外面的一层数据被copy开辟了一个新的存储空间,但是list2的里面一层依然指向对象list1的空间,所以list1的里层改变,会导致list2的里层改变。

>>> import copy
>>> list1=[1,2,3,[1,2,3]]
>>> list2=copy.copy(list1)
>>> print(list1)
[1, 2, 3, [1, 2, 3]]
>>> print(list2)
[1, 2, 3, [1, 2, 3]]
>>> list1.append(4)
>>> list1[3]=[1,2]    # list1[3]这个元素,被重新初始化,开辟了新的存储空间
>>> print(list1)       
[1, 2, 3, [1, 2], 4]                    #  最外一层被复制了,开辟了新空间,原始数据的修改不会影响新数据
>>> print(list2)
[1, 2, 3, [1, 2, 3]]                   #  里层的不复制,并且list1[3]=[1,2]又开辟了新的空间,所以这里list2还是指向原空间[1, 2, 3]
>>>

python 数字复制为变为固定长度的数组_数据结构与算法_09

此图中,list1[3]没有开辟新的存储空间,list1和list2的里层依然指向这里。

 

实现浅copy的三种方式:

p1=copy.copy(names)   # copy模块
p2=names[:]       # 分片
p3=list(names)    # 工厂函数

 

深拷贝

包含对象里面的子对象的拷贝,所以原始对象的改变不会造成深拷贝里任何子元素的改变;深拷贝相当于给被拷贝的对象另外开辟一个存储空间,list2指向新的存储空间,原始list1的改变,不会对该空间产生任何影响。

注意:

一般使用深copy的情况比较少,因为深copy完全复制了一份数据,占用太多的存储空间。

>>> import copy
>>> list1=[1,2,3,[1,2,3]]
>>> list2=copy.deepcopy(list1)      # 深复制
>>> print(list1,list2)
[1, 2, 3, [1, 2, 3]] [1, 2, 3, [1, 2, 3]]
>>> list1.append(4)
>>> list1[3].append(4)
>>> print(list1,list2)
[1, 2, 3, [1, 2, 3, 4], 4] [1, 2, 3, [1, 2, 3]]
>>>