在没有说深浅copy之前,先说一下变量。变量是的数据类型取决于变量的值,变量原本没有值,赋值之后的值是什么数据类型,变量就是什么数据类型。变量的值存在内存中,变量的作用就是通过变量名查找变量值。举个例子,我们每个人都有一个身份证,在身份证上有一个身份证号。在中国,所有人的身份证号都是独一无二的。我们可以把身份证号理解为内存地址,如果想知道别人的身份证号,需要看一眼。但是身份证号不只是本人一个人知道,公安局备案也有留存身份证号。我和公安局备案查询的系统都可以理解为变量,因为我们都可以找到我的身份证号。变量的赋值就是把同一个内存地址指向多个不同的变量名。

赋值

我们先创建一个变量,变量的值可以是任何数据类型,这里先用一个列表表示变量的值,为了方便后面修改变量的值。

#!/usr/bin/python3

#coding:utf-8

#吴老二个人博客~~~www.wulaoer.org

wulaoer = [1,3,4,["python","ruby","golong"],"java"]

wulaoer1 = wulaoer

print("原列表的内存地址",id(wulaoer),id(wulaoer[2]),id(wulaoer[3]),id(wulaoer[4]))

print("赋值后的内存地址",id(wulaoer1),id(wulaoer1[2]),id(wulaoer1[3]),id(wulaoer1[4]))

输出结果:

原列表的内存地址 2282250815880 1491758192 2282250816264 2282247959640

赋值后的内存地址 2282250815880 1491758192 2282250816264 2282247959640

我们发现,赋值前后不同的变量名的内存地址是一样的,这就代表两个变量名共用一个内存地址,修改其中一个,另一个变量必定改变。这是针对可变数据类型,如果不可变数据类型,修改其中一个代表重新分配内存地址。

#!/usr/bin/python3

#coding:utf-8

#吴老二个人博客~~~www.wulaoer.org

wulaoer = [1,3,4,["python","ruby","golong"],"java"]

wulaoer1 = wulaoer

print("原列表的内存地址",id(wulaoer),id(wulaoer[2]),id(wulaoer[3]),id(wulaoer[4]))

print("赋值后的内存地址",id(wulaoer1),id(wulaoer1[2]),id(wulaoer1[3]),id(wulaoer1[4]))

#列表修改

wulaoer[1]=8

print("修改后原列表的内存地址",id(wulaoer),id(wulaoer[2]),id(wulaoer[3]),id(wulaoer[4]))

print("修改后赋值后的内存地址",id(wulaoer1),id(wulaoer1[2]),id(wulaoer1[3]),id(wulaoer1[4]))

print("#######################################分割线#################################################")

wolf='python3'

wolf1=wolf

print("字符串的内存地址",id(wolf),id(wolf[1]),id(wolf[4]),id(wolf[5]))

print("字符串的内存地址",id(wolf),id(wolf[1]),id(wolf[4]),id(wolf[5]))

#字符串修改后重新赋值

wolf=wolf.replace('3','2')

print("修改后字符串的内存地址",id(wolf),id(wolf[1]),id(wolf[4]),id(wolf[5]))

print("修改后字符串的内存地址",id(wolf),id(wolf[1]),id(wolf[4]),id(wolf[5]))

输出结果:

原列表的内存地址 1142802934152 1491758192 1142802934536 1142800069720

赋值后的内存地址 1142802934152 1491758192 1142802934536 1142800069720

修改后原列表的内存地址 1142802934152 1491758192 1142802934536 1142800069720

修改后赋值后的内存地址 1142802934152 1491758192 1142802934536 1142800069720

#######################################分割线#################################################

字符串的内存地址 1142802560144 1142799002624 1142799794896 1142799047232

字符串的内存地址 1142802560144 1142799002624 1142799794896 1142799047232

修改后字符串的内存地址 1142802561544 1142799002624 1142799794896 1142799047232

修改后字符串的内存地址 1142802561544 1142799002624 1142799794896 1142799047232

列表是可变类型,修改内存地址值后内存地址一样,字符串是不可变类型,需要把修改后的值重新赋值给变量,会重新生成一个新的内存地址。总结,赋值就是通过变量引用内存地址。

数据copy分为深copy和浅copy,两者的区别:改变原始对象中为可变类型的元素的值,会同时影响拷贝对象;改变原始对象中为不可变类型的元素的值,不会响拷贝对象。看下面的例子:

#!/usr/bin/python3

#coding:utf-8

#吴老二个人博客~~~www.wulaoer.org

import copy

wulaoer = [1,3,4,["python","ruby","golong"],"java"]

wulaoer1 = copy.copy(wulaoer)#浅copy

print("原列表的内存地址",id(wulaoer),id(wulaoer[2]),id(wulaoer[3]),id(wulaoer[4]))

print("赋值后的内存地址",id(wulaoer1),id(wulaoer1[2]),id(wulaoer1[3]),id(wulaoer1[4]))

wulaoer[3][0]="python3"

print("浅copy前",wulaoer)

print("浅copy后",wulaoer1)

print("原列表的内存地址",id(wulaoer),id(wulaoer[2]),id(wulaoer[3]),id(wulaoer[4]))

print("赋值后的内存地址",id(wulaoer1),id(wulaoer1[2]),id(wulaoer1[3]),id(wulaoer1[4]))

print("##########################修改数据########################################")

wulaoer[0]=27

print("原列表的内存地址",id(wulaoer),id(wulaoer[2]),id(wulaoer[3]),id(wulaoer[4]))

print("赋值后的内存地址",id(wulaoer1),id(wulaoer1[2]),id(wulaoer1[3]),id(wulaoer1[4]))

print("修改copy前",wulaoer)

print("修改copy后",wulaoer1)

输出结果:

原列表的内存地址 1901896845640 1491758192 1901896934088 1901893989352

赋值后的内存地址 1901896845704 1491758192 1901896934088 1901893989352

浅copy前 [1, 3, 4, ['python3', 'ruby', 'golong'], 'java']

浅copy后 [1, 3, 4, ['python3', 'ruby', 'golong'], 'java']

原列表的内存地址 1901896845640 1491758192 1901896934088 1901893989352

赋值后的内存地址 1901896845704 1491758192 1901896934088 1901893989352

##########################修改数据########################################

原列表的内存地址 1901896845640 1491758192 1901896934088 1901893989352

赋值后的内存地址 1901896845704 1491758192 1901896934088 1901893989352

修改copy前 [27, 3, 4, ['python3', 'ruby', 'golong'], 'java']

修改copy后 [1, 3, 4, ['python3', 'ruby', 'golong'], 'java']

先对比一下浅copy的前后对比,浅copy前后只有最顶层的内存地址发生了变化,嵌套的列表地址没有改变。修改嵌套的列表,浅copy的列表也跟着改变,修改外层的列表,浅copy后的列表不发生改变。

深copy

#!/usr/bin/python3

#coding:utf-8

#吴老二个人博客~~~www.wulaoer.org

import copy

wulaoer = [1,3,4,{"python":"ruby"},"java"]

wulaoer1 = copy.deepcopy(wulaoer)

wulaoer.append("DevOps")

print(wulaoer)

print(wulaoer1)

print("深copy前的内存地址 ",id(wulaoer),id(wulaoer[2]),id(wulaoer[3]),id(wulaoer[4]))

print("深copy后的内存地址 ",id(wulaoer1),id(wulaoer1[2]),id(wulaoer1[3]),id(wulaoer1[4]))

wulaoer[3]["golong"]="DevOPS"

print(wulaoer)

print(wulaoer1)

print("深copy前修改的内存地址",id(wulaoer),id(wulaoer[2]),id(wulaoer[3]),id(wulaoer[4]))

print("深copy后修改的内存地址",id(wulaoer1),id(wulaoer1[2]),id(wulaoer1[3]),id(wulaoer1[4]))

输出结果:

[1, 3, 4, {'python': 'ruby'}, 'java', 'DevOps']

[1, 3, 4, {'python': 'ruby'}, 'java']

深copy前的内存地址 2223699337928 1491758192 2223696350808 2223696393192

深copy后的内存地址 2223699253576 1491758192 2223699325648 2223696393192

[1, 3, 4, {'python': 'ruby', 'golong': 'DevOPS'}, 'java', 'DevOps']

[1, 3, 4, {'python': 'ruby'}, 'java']

深copy前修改的内存地址 2223699337928 1491758192 2223696350808 2223696393192

深copy后修改的内存地址 2223699253576 1491758192 2223699325648 2223696393192

深copy后第二层的数据发生了改变,和第一层完全独立了。原列表发生了改变,新列表不变。这是可变类型的深浅copy,下面看一下不可变类型的深浅copy

#!/usr/bin/python3

#coding:utf-8

#吴老二个人博客~~~www.wulaoer.org

import copy

wulaoer="python"

wulaoer1=copy.copy(wulaoer)

print(id(wulaoer),id(wulaoer1))

wulaoer="python3"

print(wulaoer,wulaoer1)

print(id(wulaoer),id(wulaoer1))

输出结果:

2298893382632 2298893382632

python3 python

2298893381960 2298893382632

浅copy的内存地址不变,修改原字符串,新字符串不会跟着改变

总结:

不论针对列表还是字典,浅拷贝时,修改的元素类型是可变类型时,他变我也变,修改的类型是不可变类型时,他变我不变。

不论针对列表还是字典,深拷贝时,他变我不变。

可变类型:字典、列表。

不可变类型:整型、字符串、元组。

python3 copy_Python3数据的深浅copy和赋值 | 吴老二相关推荐

  1. python拷贝文件函数_python笔记2小数据池,深浅copy,文件操作及函数初级

    小数据池就是在内存中已经开辟了一些特定的数据,经一些变量名直接指向这个内存,多个变量间公用一个内存的数据. int: -5 ~ 256 范围之内 str: 满足一定得规则的字符串. 小数据池: 1,节 ...

  2. python3生成器与迭代器_python3迭代器和生成器 | 吴老二

    迭代函数就是一个利用for...in来完成的一个过程,但是呢?在没说迭代函数之前我们需要了解一下什么是迭代器,什么是生成器,两者的区别是什么,先一个一个的学习. 迭代器 先学习一下什么是迭代器,迭代器 ...

  3. [转载] python创建集合、计算a|b_python之路(集合,深浅copy,基础数据补充)

    参考链接: Python 集合set | symmetric_difference 一.集合:类似列表,元组的存储数据容器,不同点是不可修改,不可重复.无序排列. 1.创建集合: (1).set1 = ...

  4. Python基础三--字典,集合,编码,深浅copy,元祖、文件操作

    字典 dict数据类型划分:可变数据类型,不可变数据类型不可变数据类型: 元组,bool值,int,str 可哈希可变数据类型: list,dict,set 不可哈希 dict key :必须是不可变 ...

  5. python3 copy_python3 深浅copy对比详解

    一.赋值对比 1.列表 l1 = [1,2,3] l2 = l1 l1.append('a') print(l1,l2) #[1, 2, 3, 'a'] [1, 2, 3, 'a'] print(id ...

  6. Python_赋值和深浅copy

    Python中赋值和深浅copy存储变化 在刚学python的过程中,新手会对python中赋值.深浅copy的结果感到丈二和尚.经过多次在网上查找这几个过程的解释说明以及实现操作观察,初步对这几个过 ...

  7. python集合数据对象_python学习第七天 基础数据类型补充 深浅copy 集合 关键字后面加可迭代对象...

    在基础数据类型中可能遇到的坑: 元组: tuple1=(1) 的数据类型是int , tuple2=('alex')的数据类型是str 等 tuple1=(1,) 和 tuple2的数据类型是 tup ...

  8. dya6小数据池、集合、编码、深浅copy

    一.小知识点: 1.id:测试内容的内存地址 s = 'abc' print(id(s) >>> 2174306953568 2.is:判断内存地址是否相等 s = 'abc' s1 ...

  9. python怎么设置颜色深浅变化_Python赋值、深浅copy

    Python赋值.深浅copy assignment: 在 Python 中,对象的赋值就是简单的对象引用,这点和 C++不同,如下所示 a = [1, 2, 'hello', ['python', ...

最新文章

  1. 跨区域MPLS TE
  2. 使用perf监控Linux内核网络丢弃的数据包
  3. tomcat jar包_tomcat学习|tomcat中的类加载器
  4. expressjs路由和Nodejs服务器端发送REST请求 - - ITeye博客
  5. VB实现6大排序算法---动态过程展示(建议收藏)
  6. 安装Linux操作系统
  7. 机器学习基础(二十四)—— Random Forest
  8. Pycharm 新版本打开md文件卡死-解决办法
  9. 自动驾驶-毫米波雷达系列基础篇-测速原理
  10. 如何科学进行用户分析?六大方法论了解一下!
  11. Oracle 11g 扩展UNDO表空间
  12. 从零开始 了解C++
  13. 【答粉丝问】桌面运维需要具备的技能有什么?
  14. CSS学习笔记7PS切图与仿学成在线例子
  15. uniapp 自写模糊查询
  16. Jetson Nano从零开始(2):硬件篇
  17. 人工智能学习笔记 python实现梯度下降法对多元函数求解
  18. 冲刺!这篇 1658 页的《Java 面试突击核心讲》学明白保底年薪 30w
  19. python画图大全_python画图教程
  20. C语言程序设计教程 北京邮电,C语言程序设计教程第3章_北京邮电大学出版社.ppt...

热门文章

  1. QGIS与国产操作系统兼容性测试(Deepin、优麒麟、中标麒麟)
  2. windows 7宣布停止xp
  3. 信号--Signal
  4. 差速轮轮速计建模和优化量求导
  5. Java后台项目开发规范
  6. 软考初级程序员—计算机基础试题与解析(待补充)
  7. 分享功能(分享到新浪微博、腾讯微博、人人网、QQ空间。。。)
  8. 微博分享按钮 网站设置分享到微博 网站怎么添加微博分享按钮
  9. 白话说CC-信息安全通用标准CC是什么?评估保障级EAL有是什么?如何获得信息安全认证证书
  10. ubantu虚拟机搭建xl2tp服务