Вложенный список "Deep Copy" без использования функции Deepcopy - PullRequest
4 голосов
/ 21 октября 2011

Я пытаюсь скопировать вложенный список a, но не знаю, как это сделать без с помощью функции copy.deepcopy.

a = [[1, 2], [3, 4]]

Я использовал:

b = a[:]

и

b = a[:][:]

Но все они оказываются мелкими копиями.

Есть намеки?

Ответы [ 4 ]

8 голосов
/ 21 октября 2011

Моя запись для симуляции copy.deepcopy:

def deepcopy(obj):
    if isinstance(obj, dict):
        return {deepcopy(key): deepcopy(value) for key, value in obj.items()}
    if hasattr(obj, '__iter__'):
        return type(obj)(deepcopy(item) for item in obj)
    return obj

Стратегия: перебирать каждый элемент переданного объекта, рекурсивно опускаясь до элементов, которые также являются итерируемыми, и создавая новые объекты того же типа.

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

[1] Действительно! Суть в том, чтобы продемонстрировать, а не охватить все возможные варианты. Источник copy.deepcopy имеет длину 50 строк, а это не обрабатывает все.

5 голосов
/ 21 октября 2011

Вы можете использовать LC, если есть только один уровень.

b = [x[:] for x in a]
1 голос
/ 17 июля 2013

Это полный обман - но он будет работать для списков "примитивов" - списков, диктов, строк, чисел:

def cheat_copy(nested_content):
  return eval(repr(nested_content))

Вероятно, для этого есть смысл - и он не будетособенно быстро.

0 голосов
/ 21 октября 2011

Я нашел способ сделать это с помощью рекурсии.

def deep_copy(nested_content):
    if not isinstance(nested_content,list):
        return nested_content
    else:
        holder = []
        for sub_content in nested_content:
            holder.append(deep_copy(sub_content))
        return holder
...