1

From my understanding of deep/shallow copying. Shallow copying assigns a new identifier to point at the same object.

>>>x = [1,2,3]
>>>y = x
>>>x,y
([1,2,3],[1,2,3])
>>>x is y
True
>>>x[1] = 14
>>>x,y
([1,14,3],[1,14,3])

Deep copying creates a new object with equivalent value :

>>>import copy
>>>x = [1,2,3]
>>>y = copy.deepcopy(x)
>>>x is y
False
>>>x == y
True
>>>x[1] = 14
>>>x,y
([1,14,3],[1,2,3])

My confusion is if x=y creates a shallow copy and the copy.copy() function also creates a shallow copy of the object then:

>>> import copy
>>> x = [1,2,3]
>>> y = x
>>> z = copy.copy(x)
>>> x is y
True
>>> x is z
False
>>> id(x),id(y),id(z)
(4301106640, 4301106640, 4301173968)

why it is creating a new object if it is supposed to be a shallow copy?

Martin Spasov
  • 315
  • 3
  • 7
  • 23
  • 1
    `x = y` is simply a new assignment to the same object, no copying happens there. – Ashwini Chaudhary Sep 24 '14 at 10:32
  • then what is the difference between copy.deepcopy() and copy.copy() if they both create a new object with new address in memory ? – Martin Spasov Sep 24 '14 at 10:34
  • 2
    `copy.copy` only affects the outer container, inner objects won't be affected by that. That's where deepcopy comes into play, it will recursively create copy of all contained objects. Try with a list of lists for example. Related: http://stackoverflow.com/a/17599215/846892 – Ashwini Chaudhary Sep 24 '14 at 10:35

1 Answers1

1

A shallow copy creates a new list object and copies across all the references contained in the source list. A deep copy creates new objects recursively.

You won't see the difference with just immutable contents. Use nested lists to see the difference:

>>> import copy
>>> a = ['foo', 'bar', 'baz']
>>> b = ['spam', 'ham', 'eggs']
>>> outer = [a, b]
>>> copy_of_outer = copy.copy(outer)
>>> outer is copy_of_outer
False
>>> outer == copy_of_outer
True
>>> outer[0] is a
True
>>> copy_of_outer[0] is a
True
>>> outer[0] is copy_of_outer[0]
True

A new copy of the outer list was created, but the contents of the original and the copy are still the same objects.

>>> deep_copy_of_outer = copy.deepcopy(outer)
>>> deep_copy_of_outer[0] is a
False
>>> outer[0] is deep_copy_of_outer[0]
False

The deep copy doesn't share contents with the original; the a list has been recursively copied as well.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343