python 深浅复制与指针内存
Python是一门非常好的语言,他的长处在于拥有巨大灵活性的同一时候也拥有无比的严谨性,其它语言规定了非常多语法。告诉你什么情况下,语法就是这种,而Python却用非常少的规定,延伸出非常多语法,有些语法看上去非常奇怪,细致分析却是那么的合理。今天思考了Python中关于指针和深浅复制的问题,以下希望能通过依据内存空间的变化对这些让人头疼的问题作出一个解释。
首先看第一个样例:
a = 1
b = a
b = 2
print ’a = %s‘ %a, ‘b = %s’%b
结果:a = 1 b = 2
当运行a = 1操作时,内存中先分配一个整型变量的空间并赋值为1。然后将a指向这块空间,运行b = a时,将b也指向这块内存,这时,a和b的地位是一样的。b = 2。按说会把当前b指向的那块内存赋值为2,事实上Python并不会这样做。由于在Python中。整型以及其它基本类型加上字符串和元组等是不能够被改动的。意思是他们一旦被声明。在内存上就不能被改变。
那么运行b = 2时发生的是。系统分配一个整型的内存。并赋值为,再将这块内存的地址赋给b,因此a和b就指向了不同的值。
在看一个非常矛盾的样例:
a=[1,[2],3]
b=a
b[0]=0
print a
结果:[0,[2],3]
这好像不太对。和上面说的有点矛盾。事实上并不矛盾。由于列表是能够改动的,a和b指向的是一个列表,事实上列表时存的是一组指针。指针是能够改动的。元组不能改动就是由于元组里的数据是内存上的数据本身。而列表里元素是指针。
当使用b改动b[0]时,实际上是将原本指向一个1的指针b[0]同一时候也是a[0]指向了一个0。而那个1假设没有别的指针指向他的话。他就被回收了。
这个0和1尽管索引一样,但在内存中的位置不同。我无比的希望能够打印指针的内容来验证我的想法。
内存情况例如以下:
赋值之后:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDM1MjY5NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
以下说一下copy()和deepcopy()。
deepcopy()就不用说了。这个就是严格的深复制。两个指针一点关系都没有。谁也不会影响谁。由于他们在内存中是独立的。
而copy就不行了。他是copy()有别于直接赋值,但它又不同于deepcopy()。举个样例:
import copy
a=[1,[2],3]
b=copy.copy(a)
b[0]=0
b[1].append(2)
print a
结果为:[1,[2,2],3]
折结果看似意外。事实上是十分合理的。copy()是一种浅复制,b实际上是a的一个影子。系统也为b分配了自己的空间。意味着a和b指向的内存并不同样。可是,b中仅仅复制了a中的指针。意思是b的每一项和a中的每一项指向的内存是同样的。当对b[0]赋值为0时,b[0]从指向1改为指向0,而a[0]还是指向1的,因此a的第一项仍为1。而b[1].append(2)时,b[1]和a[1]指向同一个列表,这个列表就是[2]。
这条语句并没有改动指针而是让[2]添加了一个元素。a[1]和b[1]还是指向这个列表的。
因此a[1]变为[2,2]。
画一下的话应该是这个样子:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDM1MjY5NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
上图是copy()过后的内存情况。
经过操作后内存的情况例如以下:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDM1MjY5NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
上面v就是我对Python内存管理和指针的理解。如有错误,请指正。
python 深浅复制与指针内存的更多相关文章
- Python 深浅复制
(一)浅复制 复制列表最简单的方式是使用内置类型的构造方法: >>> l1 = [1, [2, 3], (4, 5)] >>> l2 = list(l1) > ...
- 2019-04-15 python深浅复制
原作地址:https://www.cnblogs.com/xueli/p/4952063.html 在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,pyth ...
- 【Python初级】由判定回文数想到的,关于深浅复制,以及字符串反转的问题
尝试用Python实现可以说是一个很经典的问题,判断回文数. 让我们再来看看回文数是怎么定义的: 回数是指从左向右读和从右向左读都是一样的数,例如1,121,909,666等 解决这个问题的思路,可以 ...
- python基础学习之深浅复制的概念
1.深浅复制 浅复制,python自带,深复制需要导入模块包 import copy 使用深浅复制,根据id不同写出他们的区别a = [1,2,3]b = [6,7,8]s1 = [a,b]print ...
- Python基础之列表深浅复制和列表推导式
一.列表深浅复制: 浅拷贝内存图如下: 深拷贝内存图如下: 二.列表推导式: 实例: """ 列表推导式 练习:exercise01 """ ...
- Python 字符串拼接、格式化输出、深浅复制
拼接:"+"号(同类型可拼接) >>>li = [1,2] >>>li + li [1,2,1,2] >>>li*2 [1,2 ...
- Python格式化输出和深浅复制
字符串的四种拼接方法,常用格式化 deepcopy(深复制) bytes 和 bytearray 的基本用法 字符串拼接 使用 + 格式化字符串 使用join 用单引号内的字符来拼接,参数填一个整体 ...
- python基础知识03-格式化输出和深浅复制
VIM中HJKL可以上下左右移动光标. 格式化输出和深浅复制 1.字符串的拼接和格式化 sudo pip3 install ipython 安装 ipython 进入 字符串相加 str1 + str ...
- 详谈OC(object-c)深浅复制/拷贝-什么情况下用retain和copy
读前小提示:对于深浅复制有一个清楚的了解,对于学习oc的朋友来说,至关重要.那么首先,我们要明白深浅复制是如何定义的呢.这里为了便于朋友们理解,定义如下. 浅 复 制:在复制操作时,对于被复制的对象的 ...
随机推荐
- linux破解root登录密码,并重置
重启系统后按'e'键,进入编辑模式,在'UTF -8'后空格输入'rd.break'后,按快捷键'Ctrl+X'进入新界面进行编辑,代码如下: switch_root:/# mount -o remo ...
- VMware搭建内网并通过iptables端口转发联网
整体流程图 配置Server1 新建两块网卡 一块网卡设置为桥接模式,另外一块设置为仅主机模式 查看两块网卡配置 root@ubuntu:~# ifconfig ens33 Link encap:Et ...
- p3386 二分图匹配模板
https://www.luogu.org/problemnew/show/P3386 可以只做一边的匹配 #include <bits/stdc++.h> using namespace ...
- c#导出word文档
为方便下次遇到不知道去哪找先把它存放在这里,以下是保存导出word主要类方法 public class BiultReportForm { /// <summary>word 应用对象 & ...
- LA 4064 (计数 极角排序) Magnetic Train Tracks
这个题和UVa11529很相似. 枚举一个中心点,然后按极角排序,统计以这个点为钝角的三角形的个数,然后用C(n, 3)减去就是答案. 另外遇到直角三角形的情况很是蛋疼,可以用一个eps,不嫌麻烦的话 ...
- spring源码深度解析—Spring的整体架构和环境搭建
概述 Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用.Spring是于2003 年兴起的一个轻量级的Java 开发框 ...
- Leetcode 236.二叉树的最近公共祖先
二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x ...
- 【HTML/XML 5】使用XSL给XML文档添加样式
导读:上篇博客中以具体实例分析了HTML和XML在语义上的不同,但是,大家也都发现,XML表现出来的,并没有HTML那样直观或者说美观.其原因是因为XML的表现内容和表现形式被分离.它的表现形式有两种 ...
- 2016上海站EC-final总结!
2016上海站EC-final总结 本想在知乎上发起一个话题:没有半点准备实力菜得抠脚的选手突然有机会参加final是什么体验.不过感觉这样太高调了,于是..... 以上说的就是事实,毫无准备.毫无状 ...
- 禁止ScrollView在子控件的布局改变时自动滚动的的方法
重写scrollview中的如下方法,并将其返回值设为0即可. @Override protected int computeScrollDeltaToGetChildRectOnScreen(Re ...