Python中的赋值和拷贝

赋值

在python中,赋值就是建立一个对象的引用,而不是将对象存储为另一个副本。例如:

>>> a=[1,2,3]
>>> b=a
>>> c=a

对象是[1,2,3],分别由a、b、c三个变量其建立了对应的引用关系。而三个变量都不独占对象[1,2,3],或者说,可以通过任何一个变量来修改[1,2,3]这个对象。

>>> c.append(4)
>>> c
[1, 2, 3, 4]
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
>>> b.append("from b")
>>> b
[1, 2, 3, 4, 'from b']
>>> a
[1, 2, 3, 4, 'from b']
>>> c
[1, 2, 3, 4, 'from b']

拷贝

拷贝有浅拷贝和深拷贝之分。首先看下面的例子

>>> a=[1,2,3]               #建立a与对象的引用连接
>>> b=a                     #通过赋值,b也与对象建立引用
>>> import copy
>>> c=copy.copy(a)          #浅拷贝,建立了一个[1,2,3]的副本,即一个新的对象
>>> d=copy.deepcopy(a)      #深拷贝,建立了一个[1,2,3]的副本。

至此,a、b、c、d的关系如下图所示:

a--|

|-->[1,2,3]

b--|

c----->[1,2,3]

d----->[1,2,3]

修改a

>>> a.append('aa')          #通过变量a修改原对象,使它变成[1,2,3,'aa']
>>> b                       #b也同步改变
[1, 2, 3, 'aa']
>>> c                       #c对应的是一个副本,没有受到影响
[1, 2, 3]
>>> d                       #d同上道理
[1, 2, 3]

a、b、c、d的关系如下图所示:

a--|

|-->[1,2,3,‘aa‘]

b--|

c----->[1,2,3]

d----->[1,2,3]

修改c:

>>> c.append("cc")          #修改c的对象
>>> a                       #a没有受到影响,因为a、c是指向不同对象
[1, 2, 3, 'aa']
>>> b
[1, 2, 3, 'aa']
>>> c
[1, 2, 3, 'cc']
>>> d
[1, 2, 3]

a、b、c、d的关系如下图所示:

a--|

|-->[1,2,3,‘aa‘]

b--|

c----->[1,2,3,‘cc‘]

d----->[1,2,3]

在上面的例子中,似乎copy和deepcopy没有什么区别,都是另外建立一个副本。且看如下例子:

>>> q=[1,2,3,['a','b']]         #注意,这个对象是一个list,里面还有一个元素是list,即q[3]=['a','b']
>>> w=copy.copy(q)              #w、e分别是浅拷贝和深拷贝的副本对象引用
>>> e=copy.deepcopy(q)

>>> q.append('4q')              #q所对应的[1,2,3,['a','b']]变成[1,2,3,['a','b'],'4q']
>>> q
[1, 2, 3, ['a', 'b'], '4q']
>>> w                           #w,e如同前面一样,没有受到影响
[1, 2, 3, ['a', 'b']]
>>> e
[1, 2, 3, ['a', 'b']]

修改w的对应列表

>>> w.append(4)
>>> w                           #增加了一个整数4
[1, 2, 3, ['a', 'b'], 4]
>>> q                           #q和e都没有受到影响
[1, 2, 3, ['a', 'b']]
>>> e
[1, 2, 3, ['a', 'b']]
>>> q
[1, 2, 3, ['a', 'b']]

修改w[3]的元素,提示:w是对q进行浅拷贝而得。

>>> w[3].append('w3c')
>>> q
[1, 2, 3, ['a', 'b', 'w3c']]
>>> w
[1, 2, 3, ['a', 'b', 'w3c'], 4]
>>> e
[1, 2, 3, ['a', 'b']]

仔细观察上面的结果,发现:

  • q和w,当修改了列表里面的列表元素之后,两个同步修改了。
  • e没有受到影响

也就是浅拷贝,只建立了外层的副本,对于内层的副本没有建立;而深拷贝,建立了完整的副本。这就理解了汉语的翻译名称“浅”拷贝之含义了,其“浅”就是拷贝了一层(外层)。

进一步修改e看看效果:

>>> e.append('5e')
>>> q
[1, 2, 3, ['a', 'b', 'w3c']]
>>> w
[1, 2, 3, ['a', 'b', 'w3c'], 4]
>>> e
[1, 2, 3, ['a', 'b'], '5e']
>>> e[3].append('e3c')
>>> q
[1, 2, 3, ['a', 'b', 'w3c']]
>>> w
[1, 2, 3, ['a', 'b', 'w3c'], 4]
>>> e
[1, 2, 3, ['a', 'b', 'e3c'], '5e']

有思考的程序员,看到这里就会提出一个问题,为什么要有浅拷贝和深拷贝呢?它们各自是如何工作的?在神奇的网络上,对这个问题有回答,请参考以下两个连接内容:

Python中的赋值和拷贝,布布扣,bubuko.com

时间: 2024-10-10 07:55:42

Python中的赋值和拷贝的相关文章

python中的“赋值与深浅拷贝”

Python中,赋值与拷贝(深/浅拷贝)之间是有差异的,这主要源于数据在内存中的存放问题,本文将对此加以探讨. 1 赋值(添加名字) 赋值不会改变内存中数据存放状态,比如在内存中存在一个名为data的数据,此时若执行语句data_01 = data,则现在该份数据有了两个名称(data和data_01),其余都不发生改变,使用任何一个名称对数据进行操作,那么用另外一个名称拿数据时,数据会呈现之间发生的改变.示例如下: 图中,给列表分配了两个名称a与b,对a做改变时b会同样改变,对b做改变时a也会

Python中的对象的拷贝赋值操作

Python中的赋值也分传值与传地址. 用=时,传的是地址,当两者绑定到一起,其中一个发生改变时,另一个也会改变. 如: x = [1, 2, 3, 4] y = x y[0] = 5 print(x) 这时候的结果显示的是 [5, 2, 3, 4] 若要仅仅传值,则要用copy函数. x = [1, 2, 3, 4] y = x.copy() y[0] = 5 print(x) 这时候的结果就显示的是 [1, 2, 3, 4],即x的值没有改变.

python编程之赋值和拷贝的区别概述及操作excel数据库(图)

python编程之赋值和拷贝的区别概述及操作excel数据库(图)一.赋值在Python中,对象的赋值就是简单的对象引用,这点和C++不同,如下所示:a = [1,2,"hello",['python', 'C++']] b = a在上述情况下,a和b是一样的,他们指向同一片内存,b不过是a的别名,是引用.我们可以使用bisa 去判断,返回True,表明他们地址相同,内容相同,也可以使用id()函数来查看两个列表的地址是否相同.赋值操作(包括对象作为参数.返回值)不会开辟新的内存空间,

Python中有关赋值的奇怪现象

下面看两个例子: 1) 2) 看到区别了吧~~ 在第1)个例子中a的值改变不影响b的值:而在2)例子中L1的值改变了会影响L2的值. 其实并不难理解,再看第3)个例子: 小结:如果是对整个变量重新赋值,则这个变量指向原来数值的指针会断掉,转而指向新的值:而如果只是对变量里面的一部分重新赋值(改变),则只不会断掉指针,这时改变的就是内存中的数值,其他指向这个数值的输出结果也会改变. Python中有关赋值的奇怪现象,布布扣,bubuko.com

Python中变量赋值的8种形式、需要注意哪些细节?

本文解释python中变量赋值的形式,并解释一些细节. python中变量赋值的几种形式 1 x = "long" # (1).基本形式 2 x, y = "long", "shuai" # (2).元组对应赋值 3 [x, y] = ["long", "shuai"] # (3).列表对应赋值 4 a, b, c, d = "long" # (4).序列赋值 5 a, *b = 'lo

python基础(5):深入理解 python 中的赋值、引用、拷贝、作用域

在 python 中赋值语句总是建立对象的引用值,而不是复制对象.因此,python 变量更像是指针,而不是数据存储区域, 这点和大多数 OO 语言类似吧,比如 C++.java 等 ~ 1.先来看个问题吧: 在Python中,令values=[0,1,2];values[1]=values,为何结果是[0,[...],2]? >>> values = [0, 1, 2] >>> values[1] = values >>> values [0, [.

python中关于赋值、浅拷贝与深拷贝的问题

Python中关于对象复制有三种类型的使用方式,赋值.浅拷贝与深拷贝.他们既有区别又有联系,刚好最近碰到这一类的问题,研究下. 一.赋值 在python中,对象的赋值就是简单的对象引用,这点和C++不同.如下: list_a = [1,2,3,"hello",["python","C++"]] list_b = list_a 这种情况下,list_b和list_a是一样的,他们指向同一片内存,list_b不过是list_a的别名,是引用. 我们可

Python中的赋值、浅拷贝、深拷贝

在理解浅拷贝和深拷贝之前,首先要理解学习一下变量在Python中是怎样存储的: 变量的类型是分值引用与地址引用两种. python的一切变量都是对象,变量的存储,采用了地址引用的方式,存储的只是一个变量的值所在的内存地址,而不是这个变量的只本身. 在Python中,是有多种数据类型:bool.int.long.float.string.list.dict.tuple.set; 其中可分为基本数据类型和复杂数据结构: 基本数据类型:bool.int.long.float.string; 复杂数据结

Python中的赋值语法

Python中复制语法有6种 Basic Form >>>spam = 'spam' Tuple assignment >>>spam, ham = 'spam', 'ham' List assignmen >>>[spam, ham] = ['spam', 'ham'] Sequence assignment >>>a, b,c,d = 'spam' Extended sequence unpacking(Python 3.X) &