Python:deepcopy(list)vs new_list = old_list [:]

时间:2010-06-25 17:02:03

标签: python list copy

我正在从http://openbookproject.net/thinkcs/python/english2e/ch09.html进行练习#9,并且遇到了一些没有意义的事情。

练习建议使用copy.deepcopy()使我的任务更容易,但我不知道它是怎么做的。

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

我很困惑为什么这本书建议在简单的deepcopy()复制时使用list[:]。我用错了吗?我的功能完全没有了吗?

我也有一些混淆返回值。问题是上面代码中的文档。

TIA

2 个答案:

答案 0 :(得分:22)

你问了两个问题:

深层与浅层副本

matrix[:]是一个浅拷贝 - 它只复制直接存储在其中的元素,并且不会递归地复制数组或其他引用本身的元素。这意味着:

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

如果您将对象存储在a

,也会发生同样的情况

deepcopy()当然是一个深层副本 - 它以递归的方式复制每个元素,一直到树下:

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)与调用append并返回final不同,因为list.append不返回列表对象本身,它返回None

答案 1 :(得分:2)

请参阅documentation on deep and shallow copy

list[:]

不会创建嵌套元素的副本。

关于return语句的问题,当你调用它时看起来你不在函数内部,我认为这是在粘贴代码时发生的。关于返回值Michael Mrozek是对的。