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?
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.
__iter__ method). Also,this solution has poor performance and assumes the class always can handle its objects in the constructor.type(obj).__init__ can't make copies of obj. But in exchange for being only 6 lines which demonstrate the point, I can live with that. :-)type(obj)(obj) works for approximately zero class instances, limiting its scope to built-in types. And it also doesn't copy any of the immutable types, (str(s) seems to just return s directly, which is sensible as strings are immutable). But since the only types that are both mutable and builtin are iterable, you may as well just return obj, as return type(obj)(obj) claims to be copying obj but in fact it will almost never do so.You can use a LC if there's but a single level.
b = [x[:] for x in a]
deepcopy().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.
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
nested_content.__iter__, you can use type(nested_content) to create a new object of the same type. Also, you're not actually making a copy of the contents of your lists - you're building new lists referencing the original items.
b=a[:]does indeed make a new list, but its elements are references to the original items in a. For example:a=[[]];b=a[:];b[0].append(1);print ayields[[1]]because the first element in b is the same object as the first element in a. A deep copy would result in two different objects - you can try it yourself.copy.deepcopydoens't get it right out of the box in many cases (you can provide your own copy and deepcopy methods to work around that). If you're implementing this yourself, you can only get something simple by making heavily limiting assumptions i.e. "I'm only copying lists that contain only builtin types".