is dict.copy() a deep copy or a shallow copy

Discussion in 'Python' started by Alex, Sep 4, 2005.

  1. Alex

    Alex Guest

    Entering the following in the Python shell yields

    >>> help(dict.copy)

    Help on method_descriptor:

    copy(...)
    D.copy() -> a shallow copy of D

    >>>


    Ok, I thought a dictionary copy is a shallow copy. Not knowing exactly
    what that meant I went to http://en.wikipedia.org/wiki/Deep_copy where
    I could read

    "...a deep copy is copy that contains the complete encapsulated data of
    the original object, allowing it to be used independently of the
    original object. In contrast, a shallow copy is a copy that may be
    associated to data shared by the original and the copy"

    Going back to Python shell I tested the following

    >>> D={'Python': 'good', 'Basic': 'simple'}
    >>> E=D.copy()
    >>> E

    {'Python': 'good', 'Basic': 'simple'}
    >>> D['Basic']='oh my'
    >>> D

    {'Python': 'good', 'Basic': 'oh my'}
    >>> E

    {'Python': 'good', 'Basic': 'simple'}
    >>>


    Hmm, this looks like a deep copy to me?? I also tried

    >>> D={'Python': 'good', 'Basic': 'simple'}
    >>> E=D
    >>> E

    {'Python': 'good', 'Basic': 'simple'}
    >>> E['Basic']='oh my'
    >>> E

    {'Python': 'good', 'Basic': 'oh my'}
    >>> D

    {'Python': 'good', 'Basic': 'oh my'}
    >>>


    which looks like a shallow copy to me?? So my hypothesis is that E=D is
    a shallow copy while E=D.copy() is a deep copy.

    So is the documentation wrong when they claim that D.copy() returns a
    shallow copy of D, or did I misunderstand the difference between a deep
    and shallow copy?

    Thanks
     
    Alex, Sep 4, 2005
    #1
    1. Advertising

  2. Alex

    Max Erickson Guest

    "Alex" <> wrote in
    news::
    >>>> D={'Python': 'good', 'Basic': 'simple'}
    >>>> E=D.copy()
    >>>> E

    > {'Python': 'good', 'Basic': 'simple'}
    >>>> D['Basic']='oh my'
    >>>> D

    > {'Python': 'good', 'Basic': 'oh my'}
    >>>> E

    > {'Python': 'good', 'Basic': 'simple'}
    >>>>

    >
    > Hmm, this looks like a deep copy to me?? I also tried
    >


    It is shallow, but strings are immutable so the difference is fairly
    moot.

    >>>> D={'Python': 'good', 'Basic': 'simple'}
    >>>> E=D
    >>>> E

    > {'Python': 'good', 'Basic': 'simple'}
    >>>> E['Basic']='oh my'
    >>>> E

    > {'Python': 'good', 'Basic': 'oh my'}
    >>>> D

    > {'Python': 'good', 'Basic': 'oh my'}
    >>>>

    >


    Here, E and D are different names for the same object. There is no
    copy.

    > which looks like a shallow copy to me?? So my hypothesis is that
    > E=D is a shallow copy while E=D.copy() is a deep copy.
    >


    > So is the documentation wrong when they claim that D.copy()
    > returns a shallow copy of D, or did I misunderstand the
    > difference between a deep and shallow copy?


    Sort of, some examples:

    Here d1 and d2 are copies. They can be independently changed to
    refer to different objects:

    >>> d1={'a':1,'b':2}
    >>> d2=d1.copy()
    >>> d1['a']=3
    >>> d2['b']=4
    >>> d1

    {'a': 3, 'b': 2}
    >>> d2

    {'a': 1, 'b': 4}

    Again, d3 and d4 are copies, but instead of changing the objects
    they refer to, we change the contents of the objects they refer to:

    >>> d3={'c':[3],'d':[4]}
    >>> d4=d3.copy()
    >>> d3['c'][0]=5
    >>> d4['d'][0]=6
    >>> d3

    {'c': [5], 'd': [6]}
    >>> d4

    {'c': [5], 'd': [6]}

    Both cases are shallow copies. In a deep copy, altering the contents
    of d3['c'] would have no impact on the contents of d4['c'].

    max
     
    Max Erickson, Sep 4, 2005
    #2
    1. Advertising

  3. Alex

    Alex Guest

    Thanks max,
    Now it's much clearer. I made the following experiment
    >>>#1
    >>> D={'a':1, 'b':2}
    >>> D

    {'a': 1, 'b': 2}
    >>> E=D.copy()
    >>> E

    {'a': 1, 'b': 2}
    >>> D['a']=3
    >>> D

    {'a': 3, 'b': 2}
    >>> E

    {'a': 1, 'b': 2}
    >>>#2
    >>> D={'a':[1,3], 'b':[2,4]}
    >>> D

    {'a': [1, 3], 'b': [2, 4]}
    >>> E=D.copy()
    >>> E

    {'a': [1, 3], 'b': [2, 4]}
    >>> D['a'][0]=9
    >>> D

    {'a': [9, 3], 'b': [2, 4]}
    >>> E

    {'a': [9, 3], 'b': [2, 4]}
    >>>#3
    >>> import copy
    >>> F=copy.deepcopy(D)
    >>> D

    {'a': [9, 3], 'b': [2, 4]}
    >>> F

    {'a': [9, 3], 'b': [2, 4]}
    >>> D['a'][0]=7
    >>> D

    {'a': [7, 3], 'b': [2, 4]}
    >>> F

    {'a': [9, 3], 'b': [2, 4]}
    >>>


    A shallow copy of an object is a copy of the first-level data members
    and if one of the members is a pointer, then only the pointer value is
    copied, not the structure pointed to by the pointer. The original
    object and its shallow copy share the memory space occupied by these
    structures.
    A deep copy of an object is a copy of everything (including the
    structures pointe to by the pointers). The original object and its deep
    copy do not share any memory space.

    In #1 no pointers are involved so changing a value affects only D but
    not E.

    In #2 D['a'] and E['a'] are pointers that both point to the same memory
    space. Changing that memory space doesn't change the pointers
    themsleves.

    In #3 a deepcopy makes sure that a copy is made not just of the
    pointers but also of the things pointed to.

    So the lesson to be learned is that if you make a copy of a dictionary
    whose values are pointers to other structures then a deepcopy prevents
    a coupling between a the original and the copy.

    Alex
     
    Alex, Sep 5, 2005
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. VisionSet
    Replies:
    8
    Views:
    4,902
    Tris Orendorff
    Apr 29, 2004
  2. Tony Johansson

    deep and shallow copy

    Tony Johansson, May 19, 2005, in forum: C++
    Replies:
    5
    Views:
    9,830
    Rapscallion
    May 19, 2005
  3. Replies:
    1
    Views:
    544
    Victor Bazarov
    Jun 24, 2005
  4. Replies:
    26
    Views:
    2,118
    Roland Pibinger
    Sep 1, 2006
  5. shuisheng
    Replies:
    4
    Views:
    838
    Uenal S. Mutlu
    Dec 17, 2006
Loading...

Share This Page