1

My understanding for shallow copy is

a = [1,2,3]
b = a
a, b # ([1, 2, 3], [1, 2, 3])
a[0] = 99
a, b # ([99, 2, 3], [99, 2, 3])

However, Python 3 document says list.copy() Return a shallow copy of the list. Equivalent to a[:]. But this seems like a deep copy to me. Why does the documentation call it shallow copy?

a = [1,2,3]
b = a.copy()
a, b # ([1, 2, 3], [1, 2, 3])
a[0] = 99
a, b # ([99, 2, 3], [1, 2, 3])
Nico
  • 733
  • 1
  • 6
  • 7
  • becausefor `[[1,2,3,4],[5,6,7,8]].copy()` the `[1,2,3,4]` + `[5,6,7,8]` are still references NOT copies. so you get a new list with the same references inside - shallow copy. – Patrick Artner Dec 25 '17 at 15:16
  • Your list does not contain mutable items, so shallow and deep copy do not give not different results here. – Moses Koledoye Dec 25 '17 at 15:16
  • 2
    Moreover, your first example is not shallow copying, it is _aliasing_. – Ziyad Edher Dec 25 '17 at 15:16
  • @MosesKoledoye They *might* give different results. Depends on what the deep copy is doing. – Stefan Pochmann Dec 25 '17 at 15:56
  • @MosesKoledoye To demonstrate: Shallow copy: `a.copy()[0] is a[0]` is true. Deep copy: `[int.from_bytes([i], 'big') for i in a][0] is a[0]` is false. – Stefan Pochmann Dec 25 '17 at 16:05
  • @StefanPochmann That could be highly misleading for the OP at this stage. Why not use `copy.deepcopy` with the integers which returns the same interpreter int object, instead of *manufacturing* a new object with `int.from_bytes`. – Moses Koledoye Dec 25 '17 at 16:14
  • @MosesKoledoye Because `copy.deepcopy` doesn't demonstrate my point. Of course I'm using a deep copy method that does. – Stefan Pochmann Dec 25 '17 at 16:22

2 Answers2

1
a = [1,2,3,4]
b = [5,6,7,8]    
c = [a,b,25]    
d = c.copy()   # shallow, contains [a-ref,b-ref, ref of 25]

print(a)
print(b)
print(c)
print(d) 
print("")

d[2] = 99 # modify only d's 3rd element

print(a)
print(b)
print(c)
print(d) 
print("")

d[1].append(15)  # change b's refs content

print(a)
print(b)
print(c)
print(d) 
print("")

Output:

[1, 2, 3, 4]
[5, 6, 7, 8]
[[1, 2, 3, 4], [5, 6, 7, 8], 25]
[[1, 2, 3, 4], [5, 6, 7, 8], 25]

[1, 2, 3, 4]
[5, 6, 7, 8]
[[1, 2, 3, 4], [5, 6, 7, 8], 25]
[[1, 2, 3, 4], [5, 6, 7, 8], 99] # changing d[2] - its a shallow copy with 
                                 # a int thats "unique" to this list

[1, 2, 3, 4]
[5, 6, 7, 8, 15]
[[1, 2, 3, 4], [5, 6, 7, 8, 15], 25] # appended to b's ref - its just a shallow copy so
[[1, 2, 3, 4], [5, 6, 7, 8, 15], 99] # changes are in both
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • Hi Patrick, thank you so much for the detailed example. I must have confused aliasing and copying. – Nico Dec 25 '17 at 16:30
0

Your understanding of the first is wrong. b is not a copy of a, it's another name for the same thing (this is aliasing). a.copy() is a shallow copy because it only copies the first level. Try your test again with a = [ [1,2], 3].

Jack Aidley
  • 19,439
  • 7
  • 43
  • 70