Python: глубокая копия (список) vs new_list = old_list [:] - PullRequest
12 голосов
/ 25 июня 2010

Я выполняю упражнение № 9 из http://openbookproject.net/thinkcs/python/english2e/ch09.html и столкнулся с чем-то бесполезным.

В упражнении предлагается использовать 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[:] копирует его. Я использую это неправильно? Моя функция полностью вышла из строя?

У меня также есть некоторая путаница с возвратом значений. вопрос в документах в коде выше.

ТИА

Ответы [ 2 ]

22 голосов
/ 25 июня 2010

Вы задали два вопроса:

Глубокая или мелкая копия

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

2 голосов
/ 25 июня 2010

См. Документацию по глубокой и мелкой копии .

list[:]

не создает копии вложенных элементов.

Что касается вашей проблемы с оператором return, похоже, что вы не находитесь внутри функции, когда вы вызываете ее, я предполагаю, что это произошло при вставке кода здесь. Относительно возвращаемого значения Майкл Мрозек прав.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...