Как сделать абсолютно неразделенную копию сложного списка? (Глубокая копия недостаточно),

Фундаментальная идея управления версиями состоит в том, чтобы справиться несколько изменений из той же единицы информации. Идея резервного копирования состоит в том, чтобы скопировать последняя версия информации к безопасному месту - могут быть перезаписаны более старые версии.

6
задан hochl 9 October 2012 в 14:34
поделиться

5 ответов

Чтобы преобразовать существующий список списков в список, в котором нет общего доступа, вы можете рекурсивно скопировать список.

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 или классы пользователей), вам может потребоваться изменить это.

8
ответ дан 8 December 2019 в 03:53
поделиться

Когда вам нужна копия, вы явно делаете копию - загадочная [:] форма «нарезать все» идиоматична, но мне больше всего нравится гораздо больше -читаемый подход явного вызова 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, включая множественные ссылки на одни и те же подсписки! : -)

8
ответ дан 8 December 2019 в 03:53
поделиться

В зависимости от ситуации вы можете использовать глубокую копию этого списка.

5
ответ дан 8 December 2019 в 03:53
поделиться

Используйте [:] :

>>> 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 пытается рекурсивно копировать вложенные элементы и, таким образом, является более «тщательной» операцией, чем копирование .

5
ответ дан 8 December 2019 в 03:53
поделиться

Чтобы увидеть предложение Стефана в действии, сравните два вывода ниже:

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]]]
1
ответ дан 8 December 2019 в 03:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: