Python(七)拷贝

一、基本概念

变量:用来标识(identify)一块内存区域。为了方便表示内存,我们操作变量实质上是在操作变量指向的那块内存单元。编译器负责分配。我们可以使用Python内建函数id()来获取变量的地址

变量名:是一个标识符(dientify),用来代之一块内存空间,使用这个变量名,我们可以很方便的操作这块内存区域。

内存:内存是我们电脑硬件,用来存放数据,形象的理解就是内存有一个一个的小格子组成,每个格子的大小是一个字节,每个格子可以存放一个字节大小的数据。我们如何才能知道,数据存放在哪些格子中,那就得靠地址,地址类似于楼房的门牌号,是内存的标识符!

二、is和==的区别

在 Python 中一切都是对象,毫无例外整数也是对象,对象之间比较是否相等可以用==,也可以用is。

id(object)函数是返回对象object在其生命周期内位于内存中的地址,id函数的参数类型是一个对象。

==和is操作的区别

"""

is
	
(1)比较的是两个对象的id值是否相等,也就是比较俩对象是否为同一个实例对象,是否指向同一个内存地址。

==

(2)比较的是两个对象的内容是否相等,默认会调用对象的__eq__()方法。

"""

(1)不可变类型

####(1)数字####
a = 1
b = 1
print(a == b)
print(a is b)

####(2)字符串###

str1 = 'hello&jk0'
str2 = 'hello&jk0'
print(str1 == str2)  # True
print(str1 is str2)  # True

"""

小结:只有数值型和字符串型的情况下,a is b才为True

"""
t1 = (1, 2, 3)
t2 = (1, 2, 3)
print(t1 == t2) # True
print(t1 is t2) # True

#注意:3.6版本的是False,3.7版本的是True(优化)

# 分析:元组中的都是不可变元素,所以二者会相等!

# 对比实验-->元组的元素是可变类型的情况下

t1 = ([1], 2, 3)
t2 = ([1], 2, 3)
print(t1 == t2) # True
print(t1 is t2) # False

(2)可变类型

列表、字典、set等

特点:==比较的是值,is比较的是不是同一个对象(深层次)!

(3)函数的说明

##细细体会元组##

##int和字符串是会先从地址池中找,找到了就把变量的引用"=",否则就开辟新的空间!

def fun(a):
    b =(1,2,3)    #函数是独立的一个内存空间,又开辟了一个内存空间b!
    print(a==b)   #True
    print(a is b) #False
a=(1,2,3)
fun(a)

#同理-->列表和字典、set等一样!

三、深拷贝和浅拷贝

已知:= 赋值是多个变量资源共享(都指向同一块内存空间);带来的结果-->任意一个改变,即是对原内容的操作!

需求引入:我们偏偏需要将一份数据的原始内容保留一份,再去处理数据,这个时候就不能使用赋值了!

python为这种需求提供了copy模块,提供了两种主要的copy方法,一种是普通的copy(浅拷贝),另一种是deepcopy(深拷贝)!

(1)浅拷贝

       特点:不管多么复杂的数据结构,浅拷贝都只会copy一层!

       默认浅拷贝"传递对象的引用"而已,只有在复杂的数据类型中才能体现出来!

      copy能不能完成浅拷贝的动作,需要看操作的数据类型是可变的还是不可变的!

      不可变:相当于=

      可变:相当于分身,虽然穿的衣服不一样,但是一荣俱荣,一损俱损(子对象指向相同)

#####(1)元组######

import copy

a = (1, 2, 3)
b = copy.copy(a)
print(a is b)  # True -->元组是不可变数据类型-->它不会进行浅拷贝,仅仅是指向!

#####(2)列表######

c = [1, 2, 3]
d = copy.copy(c)
print(c is d)  # False-->可变类型-->所以会新建!
d.pop()
print(c)  # [1, 2, 3]
print(d)  # [1, 2]

######(3)复杂#####

e = ([1, 2, 3], 5, 6)
f = copy.copy(e)
print(id(e[0]) == id(f[0]))
print(e is f)  # True-->不可变的类型,所以不会进行浅拷贝,仅仅是指向!
e[0].append(4)
print(e)  # ([1, 2, 3, 4], 5, 6)
print(f)  # ([1, 2, 3, 4], 5, 6)

# g = [[1, 2], 5, 6]
g=[(1,2),5,6]
h = copy.copy(g)
print(g is h)  # False -->对于可变类型,会进行浅拷贝,但它们的子对象还是指向"统一对象"!
print(id(g[0]) == id(h[0]))  # True  -->

#  注意:复杂的数据结构-->可变数据类型和不可变数据类型是相对于包衣(最外层而言的)

浅拷贝和深拷贝的关系和区别

a = [1, 2, (3, 4), [5, 6]]
import copy
b = copy.copy(a)
print(a is b)
a[3].append(7)
print(a)
print(b) #说明:一致!
print('----------------------')
a.append(8)
print(a)
print(b) #说明:不一致!

小结:拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。也就是把对象复制一遍,但是该对象中引用的其他对象我不复制,也就是只拷贝第一层地址!

浅拷贝:看最外层的数据类型

(2)深拷贝

特点:完全拷贝了父对象及其子对象(递归),两者是完全独立的!

说明:能不能完成完成深拷贝的动作,看是否存在可变类型的元素或者最外层是不是可变类型

a=([1,2,3],4,(5,6,7))    False False True
a=[[1,2,3],4,(5,6,7)]    False False True
#a=[[1,2,3],4,(5,[6],7)] False False False
import copy
b=copy.deepcopy(a)
print(a is b)       #False -->深拷贝!
print(a[0] is b[0]) #False
print(a[2] is b[2]) #True-->此元素是不可变的数据类型

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值