#####################################

预备知识一——python的变量及其存储

在详细的了解python中赋值、copy和deepcopy之前,我们还是要花一点时间来了解一下python内存中变量的存储情况。

在高级语言中,变量是对内存及其地址的抽象。
对于python而言,python的一切变量都是对象,变量的存储,采用了引用语义的方式,存储的只是一个变量的值所在的内存地址,而不是这个变量的只本身。 引用语义:在python中,变量保存的是对象(值)的引用,我们称为引用语义。采用这种方式,变量所需的存储空间大小一致,因为变量只是保存了一个引用。也被称为对象语义和指针语义。
值语义:有些语言采用的不是这种方式,它们把变量的值直接保存在变量的存储区里,这种方式被我们称为值语义,
例如C语言,采用这种存储方式,每一个变量在内存中所占的空间就要根据变量实际的大小而定,无法固定下来。
值语义和引用语义的区别:
值语义: 死的、 傻的、 简单的、 具体的、 可复制的
引用语义: 活的、 聪明的、 复杂的、 抽象的、 不可复制的

#####################################

预备知识二——各基本数据类型的地址存储及改变情况

在python中的数据类型包括:bool、int、long、float、str、set、list、tuple、dict等等。

我们可以大致将这些数据类型归类为简单数据类型和复杂的数据结构。

我的划分标准是,如果一个数据类型,可以将其他的数据类型作为自己的元素,我就认为这是一种数据结构。
数据结构的分类有很多种,但是在Python中常用的只有集合、序列和映射三种结构。对应python中的set、list(tuple、str)、dict;
常用的数据类型有int、long、float、bool、str等类型。
(其中,str类型比较特别,因为从C语言的角度来说,str其实是一个char的集合,但是这与本文的关联不大,所以我们暂时不谈这个问题)
  
由于python中的变量都是采用的引用语义,数据结构可以包含基础数据类型,导致每个变量中都存储了这个变量的地址,而不是值本身;
对于复杂的数据结构来说,里面的存储的也只只是每个元素的地址而已。 这也是为什么会有可变数据类型和不可变数据类型的区别!!! 可变数据类型和不可变数据类型
1.可变数据类型:在id不变的情况下,value可改变(列表和字典是可变类型,但是字典中的key值必须是不可变类型) 2.不可变数据类型:value改变,id也跟着改变。(数字,字符串,布尔类型,都是不可类型)

更新:

1.数据类型重新初始化对python语义引用的影响

变量的每一次初始化,都开辟了一个新的空间,将新内容的地址赋值给变量。我们重复的给str1赋值,
也就是
str1 = “1212” 这是一个内存地址,
str1 = "" 在重新赋值之后就是另一个内存地址了, 2.数据结构内部元素变化重对python语义引用的影响
对于复杂的数据类型来说,改变其内部的值对于变量的影响:
当对列表中的元素进行一些增删改的操作的时候,是不会影响到lst1列表本身对于整个列表地址的,只会改变其内部元素的地址引用。
可是当我们对于一个列表重新初始化(赋值)的时候,就给lst1这个变量重新赋予了一个地址,覆盖了原本列表的地址,这个时候,lst1列表的内存id就发生了改变。
上面这个道理用在所有复杂的数据类型中都是一样的。 也就是:
list1 = [12,23,34] 这是一个内存地址
list1[0] = "" 对列表的元素操作不会影响到列表整体的内存地址,但是列表元素的内存地址会改变,
list1 = [3,3,3] 但是你对列表的整体进行赋值改变,就会影响到这个内存地址了,

#################################################

初识拷贝
我们已经详细了解了变量赋值的过程。对于复杂的数据结构来说,赋值就等于完全共享了资源,一个值的改变会完全被另一个值共享。
str2 = str1 这两个就是都是指向同一个内存地址的
list2= list1 这两个也是指向同一个内存地址的,所以是共享资源的, 然而有的时候,我们偏偏需要将一份数据的原始内容保留一份,再去处理数据,这个时候使用赋值就不够明智了。
python为这种需求提供了copy模块。提供了两种主要的copy方法,一种是普通的copy,另一种是deepcopy。我们称前者是浅拷贝,后者为深拷贝。 深浅拷贝一直是所有编程语言的重要知识点,下面我们就从内存的角度来分析一下两者的区别。

####################################################

简述Python的深浅拷贝以及应用场景?
一层的情况:
import copy
# 浅拷贝
li1 = [1, 2, 3]
li2 = li1.copy()
li1.append(4)
print(li1, li2) # [1, 2, 3, 4] [1, 2, 3] # 深拷贝
li1 = [1, 2, 3]
li2 = copy.deepcopy(li1)
li1.append(4)
print(li1, li2) # [1, 2, 3, 4] [1, 2, 3]

多层的情况:
import copy
# 浅拷贝
li1 = [1, 2, 3, [4, 5], 6]
li2 = li1.copy()
li1[3].append(7)
print(li1, li2) # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5, 7], 6]
# 深拷贝
li1 = [1, 2, 3, [4, 5], 6]
li2 = copy.deepcopy(li1)
li1[3].append(7)
print(li1, li2) # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5], 6]

###############################################

注意这个题:

v = dict.fromkeys(['k1','k2'],[])  # {'k1': [], 'k2': []}
v['k1'].append(666)
print(v) # {'k1': [666], 'k2': [666]}
v['k1'] = 777
print(v) # {'k1': 777, 'k2': [666]}

###########################################

##########################################

python语法基础-基础-赋值与深浅拷贝的更多相关文章

  1. 【python】变量的赋值、深浅拷贝

    python——赋值与深浅拷贝 https://www.cnblogs.com/Eva-J/p/5534037.html 啥都不说,看这个博主的文章!

  2. python3【基础】-赋值与深浅拷贝

    一.Python的变量及其存储 在高级语言中,变量是对内存及其地址的抽象.对于python而言,python的一切变量都是对象,变量的存储,采用了引用语义的方式,存储的只是一个变量的值所在的内存地址, ...

  3. python列表中的赋值与深浅拷贝

    首先创建一个列表 a=[[1,2,3],4,5,6] 一.赋值 a=[[1,2,3],4,5,6]b=aa[0][1]='tom'print(a)print(b)结果: [[1, 'tom', 3], ...

  4. python基础(7)--深浅拷贝、函数

    1.深浅拷贝 在Python中将一个变量的值传递给另外一个变量通常有三种:赋值.浅拷贝.深拷贝 Python数据类型可氛围基本数据类型包括整型.字符串.布尔及None等,还有一种由基本数据类型作为最基 ...

  5. python——赋值与深浅拷贝

    初学编程的小伙伴都会对于深浅拷贝的用法有些疑问,今天我们就结合python变量存储的特性从内存的角度来谈一谈赋值和深浅拷贝~~~ 预备知识一——python的变量及其存储 在详细的了解python中赋 ...

  6. python基础知识5——赋值与深浅拷贝——整数和字符串,列表元组字典

    深浅copy 一.数字和字符串 对于 数字 和 字符串 而言,赋值.浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址. 1 import copy 2 # ######### 数字.字符串 #### ...

  7. Python基础数据类型补充及深浅拷贝

    本节主要内容:1. 基础数据类型补充2. set集合3. 深浅拷贝主要内容:一. 基础数据类型补充首先关于int和str在之前的学习中已经讲了80%以上了. 所以剩下的自己看一看就可以了.我们补充给一 ...

  8. python基础(9):基本数据类型四(set集合)、基础数据类型补充、深浅拷贝

    1. 基础数据类型补充 li = ["李嘉诚", "麻花藤", "⻩海峰", "刘嘉玲"] s = "_&qu ...

  9. Python 从零学起(纯基础) 笔记 之 深浅拷贝

    深浅拷贝 1. import  copy#浅拷贝copy.copy()#深拷贝copy.deepcopy()#赋值 = 2.   对于数字和字符串而言,赋值.浅拷贝和深拷贝无意义,因为其永远指向同一个 ...

随机推荐

  1. 使用log4cxx

    在java中有log4j日志模块,使用起来非常方便,在C++中也是有的,log4cxx就是log4j的c++移植版,机缘巧合之下今天想要使用一下这个日志模块,所以记录下自己从一开始下载安装到成功使用的 ...

  2. ODBC、OLEDB和ADO之间的关系 ,以及性能比较

    学习了.net视频之后,对里面涉及到的数据库连接部分中的一些概念表示很无语.网上很多相关资料,但除了网站不一样外,基本上内容都神一样的一致. 现在,我就通过结合看到的一些资料再加上自己的理解试图去解释 ...

  3. 201512-1 数位之和 Java

    思路: mod 10获取最低位,除以10去掉最低位 import java.util.Scanner; public class Main { public static void main(Stri ...

  4. Chrome使用频率最高的快捷键

    标签 ctrl+T 打开新标签  ——— ctrl+W 关闭标签 ctrl+shift+T 打开上衣个被关闭的标签 ctrl+tab 标签向右切换 —— ctrl+shift+tab 标签向左切换 c ...

  5. 递归与树的写法-多种支付的设计-支付的接通-celery订单的回退实现

    递归与树的写法 data: data=[ {"cat_id":1,"name":"北京","parent_id":0}, ...

  6. 针对Oracle的一系列操作

    一.有关于数据库导出dmp的语句. 1 将数据库TEST完全导出,用户名system 密码manager 导出到D:\daochu.dmp中exp system/manager@TEST file=d ...

  7. 10. 通过 Dockerfile 编写 linux 命令行工具

    测试 linux 压力的工具 一. 实际操作 1. 创建一个 ubuntu 的容器 docker run -it ubuntu 2. 安装 stress 工具 apt-get update & ...

  8. JavaScript面试题(珍爱生命,远离面试)

    1.使用 typeof bar === "object" 判断 bar 是不是一个对象有神马潜在的弊端?如何避免这种弊端? 使用 typeof 的弊端是显而易见的(这种弊端同使用 ...

  9. Hadoop_课堂笔记1

    1.课程目标 实践性 2.课下需要 在家搭建一个伪分布式 3.大数据概念和意义 08年Nature第一次正式提出大数据概念 常规的数据库:结构化的数据库 TB级的结构化数据管理就很困难,需要分布式 当 ...

  10. 17.3.13---join函数

    1-----Python中有join()和os.path.join()两个函数,具体作用如下:     join():    连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符)连接生成 ...