Reputation: 2139
I'm doing exercise #9 from http://openbookproject.net/thinkcs/python/english2e/ch09.html and have ran into something that doesn't make sense.
The exercise suggests using copy.deepcopy()
to make my task easier but I don't see how it could.
def add_row(matrix):
"""
>>> m = [[0, 0], [0, 0]]
>>> add_row(m)
[[0, 0], [0, 0], [0, 0]]
>>> n = [[3, 2, 5], [1, 4, 7]]
>>> add_row(n)
[[3, 2, 5], [1, 4, 7], [0, 0, 0]]
>>> n
[[3, 2, 5], [1, 4, 7]]
"""
import copy
# final = copy.deepcopy(matrix) # first way
final = matrix[:] # second way
li = []
for i in range(len(matrix[0])):
li.append(0)
# return final.append(li) # why doesn't this work?
final.append(li) # but this does
return final
I'm confused why the book suggests using deepcopy()
when a simple list[:]
copies it. Am I using it wrong? Is my function completely out of wack?
I also have some confusion returning values. the question is documents in the code above.
TIA
Upvotes: 13
Views: 9315
Reputation: 18553
See the documentation on deep and shallow copy.
list[:]
does not create copies of nested elements.
For your problem regarding the return statement, it looks like you're not inside a function when you call it, I assume that happened while pasting the code here. Regarding the return value Michael Mrozek is right.
Upvotes: 2
Reputation: 175415
You asked two questions:
matrix[:]
is a shallow copy -- it only copies the elements directly stored in it, and doesn't recursively duplicate the elements of arrays or other references within itself. That means:
a = [[4]]
b = a[:]
a[0].append(5)
print b[0] # Outputs [4, 5], as a[0] and b[0] point to the same array
The same would happen if you stored an object in a
.
deepcopy()
is, naturally, a deep copy -- it makes copies of each of its elements recursively, all the way down the tree:
a = [[4]]
c = copy.deepcopy(a)
a[0].append(5)
print c[0] # Outputs [4], as c[0] is a copy of the elements of a[0] into a new array
return final.append(li)
is different from calling append
and returning final
because list.append does not return the list object itself, it returns None
Upvotes: 23