zoukankan      html  css  js  c++  java
  • Python 赋值、浅拷贝和深拷贝

    初学Python,和C++还是有许多不同。直接赋值、浅拷贝和深拷贝,这三种拷贝对象的操作之间还是有许多的区别。Python语言的版本为2.7,在Pycharm中进行实验。

    一、直接赋值

    用下面的代码来实验:

     1 origin = [1, "string", [1, 3, 5]]
     2 Copy = origin
     3 print Copy
     4 print id(origin), id(Copy)
     5 Copy[0] = 5
     6 print origin, Copy
     7 Copy[1] = "changed"
     8 print origin, Copy
     9 Copy[2][0] = 111
    10 print origin, Copy
    11 print id(origin), id(Copy)

    运行的结果如下:

    [1, 'string', [1, 3, 5]]
    38994824 38994824
    [5, 'string', [1, 3, 5]] [5, 'string', [1, 3, 5]]
    [5, 'changed', [1, 3, 5]] [5, 'changed', [1, 3, 5]]
    [5, 'changed', [111, 3, 5]] [5, 'changed', [111, 3, 5]]
    38994824 38994824

    可见,直接赋值的新变量完完全全就是一个原对象的引用,任何对复制对象的引用都会影响到原对象。

    二、浅拷贝

    用相同的代码来测试,仅仅把拷贝方式改成了copy.copy():

     1 import copy
     2 origin = [1, "string", [1, 3, 5]]
     3 Copy = copy.copy(origin)
     4 print Copy
     5 print id(origin), id(Copy)
     6 Copy[0] = 5
     7 print origin, Copy
     8 Copy[1] = "changed"
     9 print origin, Copy
    10 Copy[2][0] = 111
    11 print origin, Copy
    12 print id(origin), id(Copy)

    运行的结果如下:

    [1, 'string', [1, 3, 5]]
    39453768 39510280
    [1, 'string', [1, 3, 5]] [5, 'string', [1, 3, 5]]
    [1, 'string', [1, 3, 5]] [5, 'changed', [1, 3, 5]]
    [1, 'string', [111, 3, 5]] [5, 'changed', [111, 3, 5]]
    39453768 39510280

    这次可以发现,两个对象指向的内存并不相同,也就是说,浅拷贝的对象是一个新的对象。另外,可以发现,对新对象的元素进行替换并不会影响到原对象,而对子对象——列表的修改会影响到原对象。

    三、深拷贝

    同样,只是把拷贝方式换成copy.deepcopy():

     1 import copy
     2 origin = [1, "string", [1, 3, 5]]
     3 Copy = copy.deepcopy(origin)
     4 print Copy
     5 print id(origin), id(Copy)
     6 Copy[0] = 5
     7 print origin, Copy
     8 Copy[1] = "changed"
     9 print origin, Copy
    10 Copy[2][0] = 111
    11 print origin, Copy
    12 print id(origin), id(Copy)

    结果如下:

    [1, 'string', [1, 3, 5]]
    39978056 39994504
    [1, 'string', [1, 3, 5]] [5, 'string', [1, 3, 5]]
    [1, 'string', [1, 3, 5]] [5, 'changed', [1, 3, 5]]
    [1, 'string', [1, 3, 5]] [5, 'changed', [111, 3, 5]]
    39978056 39994504

    同样,两个对象指向的内存位置并不相同,说明创建了新对象。此外,新对象的任何改动都不影响到原有的对象。

    结论:

    (1)直接赋值是一个完完全全的引用,对新变量的任何改动都会影响到原对象。

    (2)浅拷贝创建了新的对象,但是只拷贝了序列的元素,对于元素也是一个序列的情况(即子对象),只复制了对这个序列的引用!

    (3)深拷贝是完完全全的拷贝,把原对象完整地拷贝到了新对象中。

  • 相关阅读:
    Median Value
    237. Delete Node in a Linked List
    206. Reverse Linked List
    160. Intersection of Two Linked Lists
    83. Remove Duplicates from Sorted List
    21. Merge Two Sorted Lists
    477. Total Hamming Distance
    421. Maximum XOR of Two Numbers in an Array
    397. Integer Replacement
    318. Maximum Product of Word Lengths
  • 原文地址:https://www.cnblogs.com/lustar/p/8372636.html
Copyright © 2011-2022 走看看