在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.swift中用let关键字类定义常量,用var关键字来定义变量. 2.swift语句的结尾不需要再带逗号,系统在运行程序时自动会帮你添加上 3.一个变量或常量必须与赋值时拥有相同的类型. 4.如果 ...

  2. ie6 js报错unterminated string constant

    原因1:读取js文件时选用的编码不匹配导致该错误. 解决办法: 方法1:修改js的存储编码.可以使用note++打开js文件,再用UTF-8编 码方式保存并取代原来的js文件即可,并且在. <s ...

  3. wait、waitpid 僵尸进程 孤儿进程

    man wait: NAME wait, waitpid, waitid - wait for process to change state SYNOPSIS #include <sys/ty ...

  4. c# 串行【序列化】和解串【反序列化】

    C#   串行[序列化]和解串[反序列化] 一. 什么是序列化和反序列话呢? 相信我们做程序的都会遇到这种情况,需要将C#中某一个结构很复杂的类的对象存储起来,或者通过网路传输到远程的客户端程序中去, ...

  5. [转]SQL语句优化技术分析

    一.操作符优化 1.IN 操作符 用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格.但是用IN的SQL性能总是比较低的,从Oracle执行的步骤来分析用IN的SQL与不用 ...

  6. BZOJ 1257 余数之和sum

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1257 题意:计算sigama(m%i)(1<=i<=n). 思路: 这样就简 ...

  7. Asp.net MVC 3实例学习之ExtShop(四)——完成产品列表页

    在完成产品列表页前要做一些准备功夫.首先是去下载MvcPager用了为产品列表分页.下载的可能是基于MVC 2的,没关系,可以用在MVC 3上.如果有担心,下载源代码重新编译一次好了.下载后将DLL添 ...

  8. java 名词解释等

    类 实例 引用 实质指针 封装 for 的不同形式 for (int i : Location) 集合类 ArrayList<Egg> = new ArrayList<Egg> ...

  9. JVM工作原理

    作为一种阅读的方式了解下jvm的工作原理 JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.exe来完成,通过下面4步来完成JVM环境. 1.创建JVM装载环境和配置 2.装载JV ...

  10. C#处理文件流的转换

    //----引入必要的命名空间 using System.IO; using System.Drawing.Imaging; //----代码部分----// private byte[] photo ...