在python中,基本上使用的是引用,那么就会造成一个隐式的内存共享,特别是在容器对象中,例如list,dictionary

对于不可变对象,是不会造成隐式的内存共享情况,如下所示:

>>> alist = [0]*5
>>> print alist
[0, 0, 0, 0, 0]
>>> alist[0]= 'kel'
>>> alist
['kel', 0, 0, 0, 0]

以上为不可变对象数字类型,数字是不可变对象,在每次都会新建这一对象。

>>> alist = ['kel']*5
>>> alist
['kel', 'kel', 'kel', 'kel', 'kel']
>>> alist[0]='changed'
>>> alist
['changed', 'kel', 'kel', 'kel', 'kel']

字符串也是不可变类型,从而在修改一个对象的时候,其他的对象都会重新建立

在多维数组列表中,则会造成隐式的内存共享,也就是修改其中一个的值其他的值也会发生改变,如下所示:

>>> multi = [[0]*5]*3
>>> multi
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
>>> multi[0][0]='kel'
>>> multi
[['kel', 0, 0, 0, 0], ['kel', 0, 0, 0, 0], ['kel', 0, 0, 0, 0]]

当使用列表解析的时候,会造成隐式内存共享,在每次使用的时候,都是指向同一个对象,具体的如下所示:

>>> row = [0]*5
>>> multi = [row]*3
>>> multi
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
>>> multi[0][0]='kel'
>>> multi
[['kel', 0, 0, 0, 0], ['kel', 0, 0, 0, 0], ['kel', 0, 0, 0, 0]]

1、 row中的五个子项都引用0 -——在这个时候修改其中之一的值,不会影响其他的值,因为是不可变对象

2、multi中的3个子项都引用row——从而在修改最里面的值的时候,都会影响其他的值,因为指向的是同一个对象row

如果对象是不可变的,则对象和对象引用实际上没什么区别。

要解决内存共享的问题,那么可以使用双层循环的列表解析,而不是使用直接使用重复的列表解析:

>>> mmultilist = [[0 for x in range(3)] for x in range(5)]
>>> mmultilist
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> mmultilist[0][0]='kel'
>>> mmultilist
[['kel', 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

在进行修改的时候,没有影响到其他的值,从而这种方法是可以的。

另外,在使用这种双层循环的方式中,可以对开始的进行简化,从而代码如下:

>>> multilist=[[0]*3 for x in range(5)]
>>> multilist
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> multilist[0][0] = 'kel'
>>> multilist
[['kel', 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

当直接使用列表乘以整数的时候,可以直接得到列表的重复,注意在这里如果是不可变对象,那么可以使用;如果涉及到了几维数据的话,那么就必须使用其中的循环从而消除对内存共享的影响。

此种问题对于可变对象才会发生,而对于不可变对象是不会发生的。

python中隐式的内存共享的更多相关文章

  1. python 中的Array,Value及内存共享

    官网文档的例子 from multiprocessing import Process, Value, Array def f(n, a): n.value = 3.1415927 for i in ...

  2. python是如何进行内存管理的

    Python引入了一个机制:引用计数. python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时, ...

  3. python面试题之Python是如何进行内存管理的

    python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时,这个对象的引用计数为0时,它被垃圾回收. ...

  4. 孤荷凌寒自学python第三十七天python的文件与内存变量之间的序列化与反序列化

    孤荷凌寒自学python第三十七天python的文件与内存变量之间的序列化与反序列化 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.什么是序列化与反序列化 序列化是指将内存中的数据进行指 ...

  5. Python是如何进行内存管理

    三个方面:一对象的引用计数机制,二垃圾回收机制,三内存池机制 一.对象的引用计数机制 Python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数. 引用计数增加的情况: 1,一个对象分 ...

  6. python是如何进行内存管理的?

    Python内存管理机制 Python内存管理机制主要包括以下三个方面: 引用计数机制 垃圾回收机制 内存池机制 引用计数 举个例子说明引用是什么: 1 如上为一个简单的赋值语句,1就是对象,a就是引 ...

  7. <Python基础>python是如何进行内存管理的

    .Python 是如何进行内存管理的?答:从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制⒈对象的引用计数机制Python 内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用 ...

  8. Python推导式详解,带你写出比较精简酷炫的代码

    Python推导式详解,带你写出比较精简酷炫的代码 前言 1.推导式分类与用法 1.1 列表推导 1.2 集合推导 1.3 字典推导 1.4 元组推导?不存在的 2.推导式的性能 2.1 列表推导式与 ...

  9. Python正则式的基本用法

    Python正则式的基本用法 1.1基本规则 1.2重复 1.2.1最小匹配与精确匹配 1.3前向界定与后向界定 1.4组的基本知识 2.re模块的基本函数 2.1使用compile加速 2.2 ma ...

随机推荐

  1. swift:创建九宫格

    九宫格的创建是有规律可循的,每一个格子的水平和竖直方向的间隔是固定的,通过计算每一个格子的位置,然后把它们依次放到视图中即可. 一般的步骤为: 1.设置格子的总个数和每一列的格子数 2.求格子的间隔: ...

  2. SSIS ->> Data Flow Design And Tuning

    Requirements: Source and destination system impact Processing time windows and performance Destinati ...

  3. 用SQLData读写数据库自定义类型

    如何读写自定义类型?SQLData是个很直观的解决办法 在oracle使用手册上找到了很好的资料 点击打开链接 http://docs.oracle.com/cd/B10501_01/java.920 ...

  4. RTC系统【转】

    http://blog.csdn.net/fanqipin/article/details/8089995 转自:http://www.cnblogs.com/muhuacat/p/5276306.h ...

  5. Linux下音频编程-输出音频文件

    程序实现了在Linux下播放Ok.wav的功能.程序首先调用fstat函数获得文件相关信息(主要是文件大小信息).通过malloc函数分配指定的内存空间,并将online.wav读入内存:然后,打开声 ...

  6. MV、MVC、MVP、MVVM简介,对MVC不确定了。

    参考: http://www.cnblogs.com/changxiangyi/archive/2012/07/16/2594297.html http://www.jcodecraeer.com/a ...

  7. debian系统安装Thinkpad T410s的无线网卡驱动:centrino Advanced-N 6200 2x2 AGN

    前几天搞到手一台小黑:T410s.自带系统是win7.由于想学习debian,所以就搞成了双系统,安装了一套debian 6.0. 可是让我困惑的是在debian下,无法使用T410s的网卡,因为默认 ...

  8. 多线程安全的HTTPCLIENT

    private static HttpClient httpClient;     static {           HttpParams params = new BasicHttpParams ...

  9. 51nod1257 背包问题 V3

    分数规划经典.开始精度1e-3/1e-4都不行,1e-5就A了 #include<cstdio> #include<cstring> #include<cctype> ...

  10. 解决VS2013调试ASP.NET中无法调试的问题:当前不会命中断点。在 XXXX.dll 中找到了 XXX.cs 的副本,但是当前源代码与 XXXX.dll 中内置的版本不同。

    解决思路: 一定是在某个文件夹存在了副本,结果果然不出所料. 当前日期是2016年3月10日,But C:\Windows\Microsoft.NET\Framework\v4.0.30319\Tem ...