Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Deep copy" nested list without using the deepcopy function

I am trying to copy the nested list a, but do not know how to do it without using the copy.deepcopy function.

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

I used:

b = a[:]

and

b = a[:][:]

But they all turn out to be shallow copy.

Any hints?

like image 785
xiaohan2012 Avatar asked Oct 21 '11 05:10

xiaohan2012


4 Answers

My entry to simulate 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

The strategy: iterate across each element of the passed-in object, recursively descending into elements that are also iterable and making new objects of their same type.

I make no claim whatsoever that this is comprehensive or without fault [1] (don't pass in an object that references itself!) but should get you started.

[1] Truly! The point here is to demonstrate, not cover every possible eventuality. The source to copy.deepcopy is 50 lines long and it doesn't handle everything.

like image 66
Kirk Strauser Avatar answered Oct 16 '22 07:10

Kirk Strauser


You can use a LC if there's but a single level.

b = [x[:] for x in a]
like image 34
Ignacio Vazquez-Abrams Avatar answered Oct 16 '22 07:10

Ignacio Vazquez-Abrams


This is a complete cheat - but will work for lists of "primitives" - lists, dicts, strings, numbers:

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

There are strong security implications to consider for this - and it will not be particularly fast. Using json.dumps and loads will be more secure.

like image 2
Danny Staple Avatar answered Oct 16 '22 09:10

Danny Staple


I found a way to do it using recursion.

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
like image 1
xiaohan2012 Avatar answered Oct 16 '22 08:10

xiaohan2012