Если нарезка не создает копию списка и list (), как я могу получить реальную копию моего списка? - PullRequest
10 голосов
/ 04 июня 2009

Я пытаюсь изменить список, и так как мои модификации становились немного сложнее, и мой список большой, я взял часть своего списка, используя следующий код

tempList=origList[0:10]
for item in tempList:
    item[-1].insert(0 , item[1])
    del item[1]

Я думал, что все изменения в списке будут влиять на объект tempList, а не на объекты origList.

Что ж, как только я правильно понял свой код и запустил его в своем первоначальном списке, первые десять элементов (с индексами 0-9) были затронуты моей манипуляцией при тестировании кода, напечатанного выше.

Итак, я гуглил это и нашел ссылки, в которых говорилось, что взятие фрагмента копирует список и создает новый. Я также нашел код, который помог мне найти идентификатор элементов, поэтому я создал свой origList с нуля, получил идентификаторы первых десяти элементов. Я снова разрезал список и обнаружил, что идентификаторы из фрагментов совпадают с идентификаторами из первых десяти элементов origList.

Я нашел больше заметок, в которых предлагался более питонный способ копирования списка:

tempList=list(origList([0:10])

Я попробовал это, и я все еще нахожу, что идентификаторы из tempList совпадают с идентификаторами из origList.

Пожалуйста, не предлагайте более эффективные способы кодирования - я сам пойму, как это сделать, в списке. Понимание самостоятельно после того, как я пойму, как работает копирование

Основываясь на ответе Кая, правильный метод:

import copy
tempList=copy.deepcopy(origList[0:10])
id(origList[0])
>>>>42980096
id(tempList[0])
>>>>42714136

Работает как шарм

Ответы [ 2 ]

24 голосов
/ 04 июня 2009

Нарезка создает мелкую копию . В вашем примере я вижу, что вы звоните insert() на item[-1], что означает, что элемент является списком списков. Это означает, что ваши мелкие копии все еще ссылаются на оригинальные объекты. Вы можете думать об этом как о создании копий указателей, а не реальных объектов.

Ваше решение заключается в использовании глубоких копий . Python предоставляет модуль копирования только для такого рода вещей. При поиске вы найдете гораздо больше информации о мелком или глубоком копировании.

4 голосов
/ 04 июня 2009

Если вы копируете объект, его содержимое не копируется. В большинстве случаев это то, что вы хотите. В вашем случае вы должны убедиться, что содержимое копируется самостоятельно. Вы можете использовать copy.deepcopy, но если у вас есть список списков или что-то подобное, я бы рекомендовал использовать copy = [l[:] for l in list_of_lists], это должно быть намного быстрее.

Небольшое примечание к вашему стилю кода:

  • del - это оператор, а не функция, поэтому лучше не использовать парены, они просто сбивают с толку.
  • Пробелы вокруг операторов и после запятых облегчили бы чтение вашего кода.
  • list (alist) копирует список, но он не более pythonic, чем alist [:], я думаю, что alist [:] используется даже чаще, чем альтернатива
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...