• python中深浅复制教程


    在python中,等号作用是引用对象地址对应的对象

    python中的数据分为可变类型和不可变类型:

    • 可变类型:可列表、字典
    • 不可变数据类型:字符串String、浮点型Float、整型Int、元祖Tuple。

    对于不可变类型数据来说,其内存地址是不变的

    # 比如:
    id(3)  # 通过id查看数据内存地址
    # 输出:
        140708771369856
    
    # 再次查看3的内存地址,可以看到和上一个3的内存地址是一样
    id(3)
    # 输出:
        140708771369856
    

    对于可变类型数据,其内存地址是不固定的

    其extend、append、+=等操作会使得其地址对应的数据发生变化。

    # 比如:
    id([1, 2])
    # 输出:
        2204932119304
    
    # 再次查看同样的数据,可以看到其内存地址已变化
    id([1, 2])
    # 输出:
        2204931521416
    
    # 所以,对于不可变类型数据,深复制和浅复制都一样,没有什么影响
    a = 3
    b = a
    print(f'a={a}, a内存地址:{id(a)}\nb={b}, b内存地址:{id(b)}')
    # 输出:
        a=3, a内存地址:140708771369856
        b=3, b内存地址:140708771369856
    

    对于可变类型数据

    • 不同的可变数据对象,即使数值相等,其内存地址也不相等
    • 如果要引用其他对象的值,最好使用深复制或浅复制
    # 若不进行深复制或浅复制:
    a = [1, 2, 3, ['a', 'b']]
    b = a
    print(f'a: {a}\na内存地址:{id(a)}\nb: {b}\nb内存地址:{id(b)}')
    print('*' * 20)
    # 改变a的值
    a += b  # a的内存地址不变,但是数据变了。注:这里的变只是对于类似于append、+=、extend等这种操作。若是直接赋值,比如a=[0, 6]这样是不会影响的。
    print(f'a: {a}\na内存地址:{id(a)}\nb: {b}\nb内存地址:{id(b)}')
    
    # 输出:
        a: [1, 2, 3, ['a', 'b']]
        a内存地址:2204931464136
        b: [1, 2, 3, ['a', 'b']]
        b内存地址:2204931464136
        ********************
        a: [1, 2, 3, ['a', 'b'], 1, 2, 3, ['a', 'b']]
        a内存地址:2204931464136
        b: [1, 2, 3, ['a', 'b'], 1, 2, 3, ['a', 'b']]
        b内存地址:2204931464136
    

    浅复制

    • 在python2中需要 import copy
    • python3中可以直接使用copy(),但是deepcopy()方法还需要导入模块
    • copy()方法称为浅复制, deepcopy()方法称为深复制
    • 浅复制是复制了新的对象,和原对象公共引用数据地址。

    建议:在内存足够的情况下,选择深拷贝,这样逻辑处理独立,不会产生上下文的影响,不容易发生难以解决的bug。

    情况1:

    a = [1, 2, 3, ['a', 'b']]
    b = a.copy()  # 浅复制
    a += b  # 改变a,对b的值没有影响
    print(f'a: {a}\na内存地址:{id(a)}\nb: {b}\nb内存地址:{id(b)}')
    
    # 输出:
        a: [1, 2, 3, ['a', 'b'], 1, 2, 3, ['a', 'b']]
        a内存地址:2204931416328
        b: [1, 2, 3, ['a', 'b']]
        b内存地址:2204932131208
    

    情况2:

    '''
    学习中遇到问题没人解答?小编创建了一个Python学习交流群:725638078
    寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
    '''
    a = [1, 2, 3, ['a', 'b']]
    b = a.copy()
    print(f'a: {a}\na内存地址:{id(a)}\nb: {b}\nb内存地址:{id(b)}')
    print('*' * 20)
    a += b
    a[3] += ['d', 'e']  # 改变a,对b的值产生影响了,这是因为b
    print(f'a: {a}\na内存地址:{id(a)}\nb: {b}\nb内存地址:{id(b)}')
    
    # 输出:
        a: [1, 2, 3, ['a', 'b']]
        a内存地址:2204931366024
        b: [1, 2, 3, ['a', 'b']]
        b内存地址:2204931363976
        ********************
        a: [1, 2, 3, ['a', 'b', 'd', 'e'], 1, 2, 3, ['a', 'b', 'd', 'e']]
        a内存地址:2204931366024
        b: [1, 2, 3, ['a', 'b', 'd', 'e']]
        b内存地址:2204931363976
    
    

    深复制

    • 在浅复制的情景2中,改变a中嵌套的列表,同样会使得b的值产生变化。
    • 为了避免这种情况产生,如果内存满足要求情况下,尽量使用深复制。
    • 深复制是完全生成新的对象,引用的是新的内存地址,两个数据间完全没有联系。
    import copy
    
    a = [1, 2, 3, ['a', 'b']]
    b = copy.deepcopy(a)
    a += b
    a[3] += ['d', 'e']
    print(f'a: {a}\na内存地址:{id(a)}\nb: {b}\nb内存地址:{id(b)}')
    
    # 输出:
        a: [1, 2, 3, ['a', 'b', 'd', 'e'], 1, 2, 3, ['a', 'b']]
        a内存地址:2204930530952
        b: [1, 2, 3, ['a', 'b']]
        b内存地址:2204930530568
    

    结尾给大家推荐一个非常好的学习教程,希望对你学习Python有帮助!

    Python基础入门教程推荐

    Python爬虫案例教程推荐

  • 相关阅读:
    HDU 1010 Tempter of the Bone
    HDU 4421 Bit Magic(奇葩式解法)
    HDU 2614 Beat 深搜DFS
    HDU 1495 非常可乐 BFS 搜索
    Road to Cinema
    Sea Battle
    Interview with Oleg
    Spotlights
    Substring
    Dominating Patterns
  • 原文地址:https://www.cnblogs.com/djdjdj123/p/15529731.html
Copyright © 2020-2023  润新知