title: What is the difference between shallow copy, deepcopy and normal assignment operation?
body: <pre><code>import copy
  
  a = "deepak"
  b = 1, 2, 3, 4
  c = [1, 2, 3, 4]
  d = {1: 10, 2: 20, 3: 30}
  
  a1 = copy.copy(a)
  b1 = copy.copy(b)
  c1 = copy.copy(c)
  d1 = copy.copy(d)
  
  
  print("immutable - id(a)==id(a1)", id(a) == id(a1))
  print("immutable - id(b)==id(b1)", id(b) == id(b1))
  print("mutable - id(c)==id(c1)", id(c) == id(c1))
  print("mutable - id(d)==id(d1)", id(d) == id(d1))
  </code></pre>
  
  <p>I get the following results:</p>
  
  <pre><code>immutable - id(a)==id(a1) True
  immutable - id(b)==id(b1) True
  mutable - id(c)==id(c1) False
  mutable - id(d)==id(d1) False
  </code></pre>
  
  <p>If I perform deepcopy:</p>
  
  <pre><code>a1 = copy.deepcopy(a)
  b1 = copy.deepcopy(b)
  c1 = copy.deepcopy(c)
  d1 = copy.deepcopy(d)
  </code></pre>
  
  <p>results are the same:</p>
  
  <pre><code>immutable - id(a)==id(a1) True
  immutable - id(b)==id(b1) True
  mutable - id(c)==id(c1) False
  mutable - id(d)==id(d1) False
  </code></pre>
  
  <p>If I work on assignment operations:</p>
  
  <pre><code>a1 = a
  b1 = b
  c1 = c
  d1 = d
  </code></pre>
  
  <p>then results are:</p>
  
  <pre><code>immutable - id(a)==id(a1) True
  immutable - id(b)==id(b1) True
  mutable - id(c)==id(c1) True
  mutable - id(d)==id(d1) True
  </code></pre>
  
  <p>Can somebody explain what exactly makes a difference between the copies? Is it something related to mutable &amp; immutable objects? If so, can you please explain it to me?</p>