Как мне скопировать только значения, а не ссылки из списка Python?
В частности, я хочу создать резервную копию списка, затем внести некоторые изменения в этот список, добавить все изменения в третий список, но затем сбросить первый список с резервной копией, прежде чем делать дальнейшие изменения и т. Д., Пока я не закончу вносить изменения и хотите скопировать весь контент из третьего списка в первый. К сожалению, кажется, что всякий раз, когда я делаю изменения в первом списке в другой функции, резервная копия также изменяется. С помощью original = backup
не работал слишком хорошо; и не использовал
def setEqual(restore, backup):
restore = []
for number in backup:
restore.append(number)
решить мою проблему; хотя я успешно восстановил список из резервной копии, резервная копия, тем не менее, менялась всякий раз, когда я изменял исходный список.
Как бы я решил эту проблему?
2 ответа
Первое, что нужно понять, это почему setEqual
метод не может работать: вам нужно знать, как работают идентификаторы. (Чтение этой ссылки должно быть очень полезным.) Для краткого изложения с, вероятно, слишком большой терминологией: в вашей функции параметр restore
привязан к объекту, и вы просто повторно связываете этот идентификатор с =
оператор. Вот несколько примеров привязки идентификатора restore
к вещам.
# Bind the identifier `restore` to the number object 1.
restore = 1
# Bind the identifier `restore` to the string object 'Some string.'
# The original object that `restore` was bound to is unaffected.
restore = 'Some string.'
Итак, в вашей функции, когда вы говорите:
restore = []
Вы фактически связываете восстановление с новым создаваемым объектом списка. Поскольку Python имеет функционально-локальную область видимости, restore
в вашем примере это привязка локального идентификатора функции restore
в новый список. Это не изменит ничего, что вы передаете setEqual
как восстановить. Например,
test_variable = 1
setEqual(test_variable, [1, 2, 3, 4])
# Passes, because the identifier test_variable
# CAN'T be rebound within this scope from setEqual.
assert test_variable == 1
Проще говоря, вы можете связывать только идентификаторы в текущей выполняемой области действия - вы никогда не сможете написать такую функцию, как def set_foo_to_bar(foo, bar)
это влияет на область за пределами этой функции. Как говорит @Ignacio, вы можете использовать что-то вроде функции копирования, чтобы перепривязать идентификатор в текущей области видимости:
original = [1, 2, 3, 4]
backup = list(original) # Make a shallow copy of the original.
backup.remove(3)
assert original == [1, 2, 3, 4] # It's okay!