tags:

views:

76

answers:

2

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

+7  A: 

You asked two questions:

Deep vs. shallow copy

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

Returning

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

Michael Mrozek
thanks for taking the time to clear it up!
centr0
+1  A: 

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.

Fabian
thanks. this further cleared it up for me and had to do it in the console to see it myself.
centr0