专栏首页python3Python3 基础(赋值与生深浅拷贝

Python3 基础(赋值与生深浅拷贝

一 python的变量与以及存储 变量是对内存的以及地址的抽象,对于python而言python的一切变量都是对象,变量的存储采用了引用语义的方式,存储的只是一个变量所在值的内存地址,而不是这个变量的本身 。 引用语义:在python中,变量的保存时对象(值)的应用,称之为引用语义,采用这种语义,变量所需存储的空间大小一致。因为变量只是一个保存的引用。

值: 把变量的值直接保存在变量的存储区域里,采用这种存储方式 ,每一个在内存中所占的空间,就要根据变量的实际大小来定,无法固定下来。

二 各个基本的数据结构地址存储以及改变情况。 在python中的数据类型包括:bool,int,long,float,str,set,list,tucp,dict 等等 , 这些数据类型可以分为简单数据类型,和复杂数据类型。 简单数据类型和复杂数据类型划分依据: 如果一个数据类型可以将其他的数据类型作为自己的元素。 则可以认为是一种数据结构,数据结构的分类有很多种,在python中常用的只有集合,序列和映射这三种数据结构 。 对应的是 set, list(tuple,str),dict,常用的数据类型有 int , long,float,bool,str 等 。 由于python中的变量都是采用的引用语义,数据结构可以包含基础数据类型,导致了在python中的数据存储方式存在下图所示的这种情况,每个变量中都存储了这个变量的地址,而不是值本身;对于复杂的数据结构来说。里面的存储也只是每个元素的地址而已

当对列表进行增,删,改查工作的时候 ,是不会影响到对于list整个本身的地址 ,只会改变其内部元素的地址应用, 可是当对列表进行重新赋值的时候,就给lst1这个列表地址赋予了一个新的地址,覆盖了原本列表的地址,这个时候,lst1的内存id就发生了变化。

内存的变化 , 其实的赋值操作都让str1,str2都存储了'hello wolrd' 是这个地址 ,重新对str1 赋值,是str1中存储的地址发生了改变,重新只想了新建的地址此时str2变量的存储的内存地址并为改变,所以不受影响。

2 复杂的数据结构的赋值

上序代码做了修改操作,但是并没有对lst2做出改变,结果lst1和lst2都发生了变化,

四 拷贝简述 上述内容讲述了变量赋值的过程,对于复杂的数据结构来说,赋值就等于完全共享了资源,一个值的改变会完全被另外一个值给共享。

五 浅拷贝 不管多么复杂的数据结构浅拷贝只会copy一层

lst = ['str1', 'str2', 'str3', 'str4', 'str5'] sourceLst = ['str1', 'str2', 'str3', 'str4', 'str5', lst] copyLst = copy.copy(sourceLst)

print('1.->sourceLst:', sourceLst) print('1.->copyLst:', copyLst)

sourceLst.append('sourcestr') copyLst.append('copystr')

print('2.->sourceLst:', sourceLst) print('2.->copyLst:', copyLst)

sourceLst[0] = 'changestr' print('3.->sourceLst:', sourceLst) print('3.->copyLst:', copyLst)

lst.append('testAppend') print('4.->sourceLst:', sourceLst) print('4.->copyLst:', copyLst)  上述代码执行会是下述结果:

复制代码 1.->sourceLst: ['str1', 'str2', 'str3', 'str4', 'str5', ['str1', 'str2', 'str3', 'str4', 'str5']] 1.->copyLst: ['str1', 'str2', 'str3', 'str4', 'str5', ['str1', 'str2', 'str3', 'str4', 'str5']] 2.->sourceLst: ['str1', 'str2', 'str3', 'str4', 'str5', ['str1', 'str2', 'str3', 'str4', 'str5'], 'sourcestr'] 2.->copyLst: ['str1', 'str2', 'str3', 'str4', 'str5', ['str1', 'str2', 'str3', 'str4', 'str5'], 'copystr'] 3.->sourceLst: ['changestr', 'str2', 'str3', 'str4', 'str5', ['str1', 'str2', 'str3', 'str4', 'str5'], 'sourcestr'] 3.->copyLst: ['str1', 'str2', 'str3', 'str4', 'str5', ['str1', 'str2', 'str3', 'str4', 'str5'], 'copystr'] 4.->sourceLst: ['changestr', 'str2', 'str3', 'str4', 'str5', ['str1', 'str2', 'str3', 'str4', 'str5', 'testAppend'], 'sourcestr'] 4.->copyLst: ['str1', 'str2', 'str3', 'str4', 'str5', ['str1', 'str2', 'str3', 'str4', 'str5', 'testAppend'], 'copystr']  上述代码中, sourceLst和copyLst中存储的都是地址,当独自修改各个list的时候,另一个不会改变。而当修改共有的lst元素的时候,sourceLst和copyLst都会发生改变,这种情况发生在字典套字典,列表套字典,字典套列表,列表套列表,以及各种复杂数据结构的嵌套中。

六、深拷贝

  上述讲述了浅拷贝,而在实际情况中,我们希望复杂的数据结构之间完全copy,而他们之间又没有一毛钱关系。

  为此,python引入了深拷贝的概念,我们可以使用copy模块中的deepcopy方法。深拷贝会完全复制原变量相关的所有数据,在内存中生成一套完全一样的内容,在这个过程中我们队这两个变量中的一个进行任意修改都不会影响其他变量。

  浅拷贝的情况:

lst1 = [1,2,3,4,[5,6,7,8]] lst2 = lst1 # 实际进行了一个浅拷贝 id(lst2) 4363600648 id(lst1) 4363600648 lst1[0] = 100 lst1 [100, 2, 3, 4, [5, 6, 7, 8]] lst2 [100, 2, 3, 4, [5, 6, 7, 8]] lst2[4][0] = 100 lst1 [100, 2, 3, 4, [100, 6, 7, 8]] 复制代码 import copy lst1 = [1,2,3,4,[5,6,7,8]] lst2 = copy.deepcopy(lst1) id(lst1) 4363594504 id(lst2) 4363593928 lst1[0] = 100 lst2 [1, 2, 3, 4, [5, 6, 7, 8]] lst2[4][0]=100 lst1 [100, 2, 3, 4, [5, 6, 7, 8]] 复制代码 从上述代码中可以看出,进行深拷贝后,lst1和lst2的地址不一样,而且两个独自修改并不影响另一个的值,他俩现在一毛钱关系都没有。

  深拷贝就是在内存中重新开辟一块空间,不管数据结构多么复杂,只要遇到可能发生改变的数据类型,就重新开辟一块内存空间把内容复制下来,知道最后一层,不再有复杂的数据类型,就保持其原引用,这样,不管数据结构多么复杂,数据之间的修改都不会相互影响。这就是深拷贝~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • H3C AP配置流程及说明

    根据AP的组网情况,保证AP设备本身的可管理性及安全性,需要对AP的名称、VLAN、SSID、接口等进行配置,具体内容如下:

    py3study
  • Python中单引号,双引号,3个单引号

    我们知道Python以其易用性而著名,所以刚开始看教程学习看到单引号和双引号都可以使用会以为这是Python为了方便程序员,随便用哪个就好,不用担心用错。其实,...

    py3study
  • promethus监控nginx

    promethues监控nginx可选两个exporter,通过nginx_exporter主要是获取nginx-status中的内建的指标,nginx自身提供...

    py3study
  • iOS应用程序的脱壳实现原理浅析

    对于诸多逆向爱好者来说,给一个app脱壳是一项必做的事情。基于安全性的考虑,苹果对上架到appstore的应用都会进行加密处理,所以如果直接逆向一个从appst...

    欧阳大哥2013
  • C(string.h)字符串操作函数总结

    功能:将字符串str2复制到字符串str1中,并覆盖str1原始字符串,可以用来为字符串变量赋值

    心跳包
  • 手残手抖不再害怕,你也可以画出逼真的肖像画

    真相可能让你大跌眼镜,第二行的帅哥美女都是AI根据第一行的灵魂画作想象出来的。神奇的是AI能准确地识别出潦草的笔触画出的发型、眉毛、眼神、脸部轮廓,甚至是嘴巴的...

    AI科技评论
  • Python学习总结4--字符串和编码

    一、编码历史     由于计算机是美国人发明的,因此,最早只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCI...

    曼路
  • 域名yg.cc以10.2万元的价格结拍,可搭建“摇滚”音乐平台

    近日,域名市场交易了不少精品域名,比如qrf.com、yg.cc等,其中qrf.com拍出15.4万元。

    躲在树上的域小名
  • UML急速入门

    类图(Class Diagram):用于表示类、接口、实例等之间相互的静态关系,虽然名字叫类图,但类图中并不只有类。我们来看一个比较全面的UML类图样例:

    端碗吹水
  • Linux进程上下文切换过程context_switch详解--Linux进程的管理与调度(二十一)

    因此当前linux的调度程序由两个调度器组成:主调度器,周期性调度器(两者又统称为通用调度器(generic scheduler)或核心调度器(core sch...

    233333

扫码关注云+社区

领取腾讯云代金券