• python内存相关以及深浅拷贝讲解


    3.9 内存相关

    3.9.1 id,查看内存地址

    >>> v1 = [11,22,33]
    >>> v2 = [11,22,33]
    >>> print(id(v1),id(v2)) # 比较两个变量的内存值
    4472652360 4473773640	
    # 对于 -5 ~ 256 的整数来说会有小地址池的概念,不会创建新的内存地址
    
    >>> v1 = "我,你,他,它,她"
    >>> v2 = "我,你,他,它,她"
    >>> print(id(v1),id(v2))
    4473666128 4473665840
    
     # 赋值,就是把v2指向了v1的内存地址,所以他们的内存地址一样
    >>> v1 = "我,你,他,它,她"
    >>> v2 = v1 
    >>> print(id(v1),id(v2))
    4473666128 4473666128
    
    # 重新赋值,v1的内存地址变了,但是v2的内存地址没变
    >>> v1 = "我,你,他,它,她"
    >>> v2 = v1    
    >>> v1 = "我,你,他,它,她,天"   v1现在指向"我,你,他,它,她,天"的地址,v2还是原来的
    >>> print(id(v1),id(v2))
    4473665840 4473666128
    >>> print(v2)
    我,你,他,它,她
    

    is,比较内存地址

    >>> v1 = {'k1':'v1','k2':[1,2,3]}
    >>> v2 = {'k1':'v1','k2':[1,2,3]}
    >>> result1 = v1 == v2
    >>> result2 = v1 is v2
    >>> print(result1)
    True
    >>> print(result2)
    False
    

    重要

    is 和 == 的区别?

    == 用于比较值是否相等。
    is 用于比较内存地址是否相等。

    PS:找到内存地址并在其中做操作和赋值 不一样

    重新赋值是重新开辟一块内存空间、可变数据类型

    #练习1(内部修改)
    v1=[11,22,33]
    v2=v1
    v1.append(666)
    print(v2) #含有666
    
    #练习2(赋值)
    v1=[11,22,33]
    v2=v1
    v1=[1,2,3,4] #此时v1重新赋值为[1,2,3,4],v1=[11,22,33] 对应的内存地址被回收,只要有指向这个内存地址的,就不会被回收
    print(v2) #[11,22,33]
    
    #练习3(重新赋值) 
    v1='alex'
    v2=v1
    v1='old boy'
    print(v2) #'alex'
    
    总结:可变数据类型列表/字典/集合 有内部修改和赋值
    字符串等不可变的 只有重新赋值(不可在内部修改)
    
    ps:
    v=[1,2,3]
    value=[11,22,v]
    value[2]=666 #对value自己更改,v不会改变
    print(v)  #[1, 2, 3]
    
    v=[1,2,3]
    value=[11,22,v]
    value[2][0]=666 #对v里面修改,v会改变
    print(v)  #[666, 2, 3]
    
    

    python中有小数据池--缓存机制,节省内存

    1. 数字 (-5-256)
    2. 简单的字符串 ‘ALEX’
    a=1
    b=1
    print(id(a),id(b)) #496846480 496846480  #理论上赋值,是重新开辟内存地址,但python中有缓存机制
    

    3.10 深浅拷贝

    浅拷贝:只拷贝第一层。浅copy会仅复制dict的第一层数据,更深层的scores下面的值依然是共享一份

    深拷贝:拷贝所有数据(只针对可变数据类型)--- 重新拷贝意味着重新在内存中开辟一块空间,都是独立的内存地址

    只有一层的深拷贝意义不大,重要的是对于嵌套

    1、int+str+bool/tuple 深浅拷贝是一样的(不可变数据类型,类似小数据池的概念)
    
    v1='alex'
    v2=copy.copy(v1)
    v3=copy.deepcopy(v1)
    print(id(v1),id(v3)) #11611168 11611168
    
    2、list+set+dict (可变数据类型)
    深浅拷贝不一样的
    

    总结

    浅拷贝:仅会拷贝a的框架的内存地址, 里面的任何子元素的内存地址都不会被拷贝.
    深拷贝:不仅拷贝a的框架,而且会拷贝a里所有的可变元素的内存地址,注意不可变元素仍不可拷贝
    
  • 相关阅读:
    joda-time的使用
    logger 的使用一 小结
    svn 技巧
    mysql 获取一段时间的数据
    Drools5
    Java各种Utils小结
    Java 8 新特新 工具类 ZonedDateTime
    集合工具类CollectionUtils、ListUtils、SetUtils、MapUtils的使用
    sonar 的使用
    MySQL入门教学(看完必懂,图文详解!)
  • 原文地址:https://www.cnblogs.com/hanfe1/p/11493112.html
Copyright © 2020-2023  润新知