For educational purposes only, I'm trying to implement the cloning function copy.deepcopy()
.
After some fun game with code and googling, I came up with the following function:
def my_deepcopy(data):
if isinstance(data, dict):
result = {}
for key, value in data.items():
result[key] = my_deepcopy(value)
assert id(result) != id(data)
elif isinstance(data, list):
result = []
for item in data:
result.append(my_deepcopy(item))
assert id(result) != id(data)
elif isinstance(data, tuple):
aux = []
for item in data:
aux.append(my_deepcopy(item))
result = tuple(aux)
assert id(result) != id(data)
elif isinstance(data, (int, float, type(None), str, bool)):
result = data
else:
raise ValueError("unexpected type")
return result
It seems to work with all the primitive types of Python and its combinations:
lst_obj = [ 0, 1.1, 'foo', 'bar' ]
dict_obj = { 'zero' : 0, 'pi' : 3.1415, 'desc' : 'foobar' }
list_list_obj = [ [1,2,3], [4,5,6], [7,8,9] ]
tuple_list_obj = [ (-1,-1), (0,-1,0), (-1,0), (0,0,0,0) ]
dict_list_obj = [ {'zero' : 0}, {'pi' : 3.1415}, {'desc' : 'foobar'} ]
my_deepcopy( lst_obj )
my_deepcopy( dict_obj )
my_deepcopy( list_list_obj )
my_deepcopy( tuple_list_obj )
my_deepcopy( dict_list_obj )
So far, so good, but what about Arbitrary Types
? How to duplicate an instance of an arbitrary object? How to detect it? Do arbitrary types have any copy constructor?
What is missing in my function for the following code to work:
class Xpto:
pass
arbitrary = [ Xpto(), Xpto() ]
my_deepcopy( arbitrary )