美文网首页
Python赋值、浅拷贝、深拷贝的区别

Python赋值、浅拷贝、深拷贝的区别

作者: StansJ | 来源:发表于2018-04-02 10:57 被阅读0次
    一、赋值
    • str例子
    >>> a = 'hello'
    >>> b = 'hello'
    >>> c = a
    >>> [id(x) for x in (a,b,c)]
    [42654216, 42654216, 42654216]
    

    a,b,c三者地址一样,相当于a=b=c。赋值系统先给变量或对象(这里的hello)分配了内存,然后将地址赋给a,b,c。所以他们的地址是相同的。

    >>> a = 'world'
    >>> [id(x) for x in (a,b,c)]
    [42654384, 42654216, 42654216]
    >>> print(a,b,c)
    world hello hello
    

    这时只有a的地址和值变了,但是b,c地址和值都没有变。因为str的不可变性,a要重新赋值则需重新开辟内存空间,所以a的值改变,a指向的地址改变。b, c由于'hello'的不变性,不会发生改变。

    • list例
    >>> a = ['hello']
    >>> b = ['hello']
    >>> c = a
    >>> [id(x) for x in (a,b,c)]
    [42670920, 42671816, 42670920]
    

    但是这种情况却不一样了,a和b的地址不同。为何?
    因为str是不可变的,所以同样是'hello'只有一个地址,但是list是可变的,所以必须分配两个地址。

    >>> a[0] = 'world'
    >>> [id(x) for x in (a,b,c)]
    [42670920, 42671816, 42670920]
    >>> print(a,b,c)
    ['world'] ['hello'] ['world']
    

    这时a,c的值和地址均改变,但二者仍相同,b不改变。由于list的可变性,所以修改list的值不需要另外开辟空间,只需修改原地址的值。所以a,c均改变。

    二、浅拷贝与深拷贝
    • 程序
    import copy
    a = [1,2,3,4,['a','b']] #原始对象
    b = a #赋值
    c = copy.copy(a) #浅拷贝
    d = copy.deepcopy(a) #深拷贝
    a.append(5)
    a[4].append('c')
    print('a = ',a)
    print('b = ',b)
    print('c = ',c)
    print('d = ',d)
    
    • 结果
    a =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
    b =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
    c =  [1, 2, 3, 4, ['a', 'b', 'c']]
    d =  [1, 2, 3, 4, ['a', 'b']]
    
    1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象。
    2. copy.deepcopy 深拷贝 拷贝对象及其子对象

    总结:

    1. 赋值是将一个对象的地址赋值给一个变量,让变量指向该地址( 旧瓶装旧酒 )。

    2. 浅拷贝是在另一块地址中创建一个新的变量或容器,但是容器内的元素的地址均是源对象的元素的地址的拷贝。也就是说新的容器中指向了旧的元素( 新瓶装旧酒 )。

    3. 深拷贝是在另一块地址中创建一个新的变量或容器,同时容器内的元素的地址也是新开辟的,仅仅是值相同而已,是完全的副本。也就是说( 新瓶装新酒 )。

    相关文章

      网友评论

          本文标题:Python赋值、浅拷贝、深拷贝的区别

          本文链接:https://www.haomeiwen.com/subject/fbpthftx.html