Remove shared references in list-of-list?

  • A+
Category:Languages

Ok, let me explain the problem with a simple example:

l = [[0]]*3       # makes the array [[0], [0], [0]] l[0][0] = 42      # l becomes [[42], [42], [42]] from copy import deepcopy m = deepcopy(l)   # m becomes [[42], [42], [42]] m[0][0] = 2       # m becomes [[2], [2], [2]] 

This is a basic shared reference problem. Except usually, when a problem like this occurs, deepcopy is our friend. Currently, I made this to solve my deepcopy betrayal problem:

l = [[0]]*3       # makes the array [[0], [0], [0]] import JSON m = JSON.loads(JSON.dumps(l)) # m becomes [[0], [0], [0]] with no self references 

I am looking for a less inefficient and less stupid way of handling self shared reference.

Of course I wouldn't make arrays like that on purpose, but I need to handle the case where someone gives one to my code. Running my "solution" on large arrays is slow, and I have many levels of nested arrays, I can't afford to make a string this big for those beasts.

 


Here's an approach that will work on any combination of lists, dicts, and immutable values.

def very_deep_copy(obj):     if isinstance(obj, list):         return [very_deep_copy(item) for item in obj]     elif isinstance(obj, dict):         return {k: very_deep_copy(v) for k,v in obj.items()}     else:         return obj  l = [[0]]*3  m = very_deep_copy(l) m[0][0] = 2 print(m) 

Result:

[[2], [0], [0]] 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: