Фундаментальная идея управления версиями состоит в том, чтобы справиться несколько изменений из той же единицы информации. Идея резервного копирования состоит в том, чтобы скопировать последняя версия информации к безопасному месту - могут быть перезаписаны более старые версии.
Чтобы преобразовать существующий список списков в список, в котором нет общего доступа, вы можете рекурсивно скопировать список.
deepcopy
будет недостаточно, так как он скопирует структуру как -is, сохранение внутренних ссылок в виде ссылок, а не копий.
def unshared_copy(inList):
if isinstance(inList, list):
return list( map(unshared_copy, inList) )
return inList
alist = unshared_copy(your_function_returning_lists())
Обратите внимание, что это предполагает, что данные возвращаются в виде списка списков (произвольно вложенных). Если контейнеры относятся к разным типам (например, массивы numpy, dicts или классы пользователей), вам может потребоваться изменить это.
Когда вам нужна копия, вы явно делаете копию - загадочная [:]
форма «нарезать все» идиоматична, но мне больше всего нравится гораздо больше -читаемый подход явного вызова list
.
Если c
сконструирован неправильно (со ссылками вместо мелких копий на списки, которые вы хотите изменить независимо), Лучше всего исправить то, как он построен (зачем строить его неправильно, а потом трудиться, чтобы исправить ?!), но если это вне вашего контроля, можно отменить повреждение - просто зацикливайтесь на c
(при необходимости рекурсивно) с индексом, переназначая соответствующие подсписки их копиям. Например, если вы точно знаете, что структура c
двухуровневая, как вы указываете, вы можете спастись без рекурсии:
def fixthewronglymadelist(c):
for topsublist in c:
for i, L in enumerate(topsublist):
topsublist[i] = list(L)
Несмотря на то, что предлагают другие ответы, copy.deepcopy
будет трудно приспособиться к этой специфической цели, если все, что вам дано, это неправильно сделанный c
: делать просто ] copy.deepcopy (c)
тщательно копирует любую топологию c, включая множественные ссылки на одни и те же подсписки! : -)
В зависимости от ситуации вы можете использовать глубокую копию этого списка.
Используйте [:]
:
>>> a = [1, 2]
>>> b = a[:]
>>> b.append(9)
>>> a
[1, 2]
В качестве альтернативы используйте copy
или deepcopy
:
>>> import copy
>>> a = [1, 2]
>>> b = copy.copy(a)
>>> b.append(9)
>>> a
[1, 2]
copy
работает с объектами, отличными от списков. Для списков он действует так же, как a [:]
. deepcopy
пытается рекурсивно копировать вложенные элементы и, таким образом, является более «тщательной» операцией, чем копирование
.
Чтобы увидеть предложение Стефана в действии, сравните два вывода ниже:
a = [1, 2, 3]
b = [4, 5, 6]
c = [[a, b], [b, a]]
c[0][0].append(99)
print c
print "-------------------"
a = [1, 2, 3]
b = [4, 5, 6]
c = [[a[:], b[:]], [b[:], a[:]]]
c[0][0].append(99)
print c
Результат следующий:
[[[1, 2, 3, 99], [4, 5, 6]], [[4, 5, 6], [1, 2, 3, 99]]]
-------------------
[[[1, 2, 3, 99], [4, 5, 6]], [[4, 5, 6], [1, 2, 3]]]