From: Westly Ward on 25 Jul 2010 20:08 x = {"type":"folder", "name":"sonicbot", "data":[{"type":"folder", "name":"SonicMail", "data":[{"type":"file", "name":"bbcode.py", "compressed":False, "contents":"blahblahfilecontents"}]}]} print x def setindict(dictionary, keys, value) : if len(keys) == 1 : if keys[0].isdigit() and int(keys[0]) == len(dictionary) : dictionary.append(keys[0]) else : dictionary[keys[0]] = value else : dictionary[keys[0]] = setindict(dictionary[keys[0]], keys[1:], value) return dictionary a = x.copy() print id(a), id(x) y = setindict(a, ["data", 0, "data", 0, "compressed"], True) if y == x : print True else : print False print x print a How are x and a are ending up the same? I would think .copy() would make it completely seperate.
From: Chris Rebert on 25 Jul 2010 20:29 On Sun, Jul 25, 2010 at 5:08 PM, Westly Ward <sonicrules1234(a)gmail.com> wrote: > x = {"type":"folder", "name":"sonicbot", "data":[{"type":"folder", > "name":"SonicMail", "data":[{"type":"file", "name":"bbcode.py", > "compressed":False, "contents":"blahblahfilecontents"}]}]} > print x > def setindict(dictionary, keys, value) : > Â Â if len(keys) == 1 : > Â Â Â Â if keys[0].isdigit() and int(keys[0]) == len(dictionary) Â : > Â Â Â Â Â Â dictionary.append(keys[0]) > Â Â Â Â else : > Â Â Â Â Â Â dictionary[keys[0]] = value > Â Â else : > Â Â Â Â dictionary[keys[0]] = setindict(dictionary[keys[0]], keys[1:], value) > Â Â return dictionary > a = x.copy() > > print id(a), id(x) > y = setindict(a, ["data", 0, "data", 0, "compressed"], True) > if y == x : > Â Â print True > > else : > Â Â print False > print x > print a > > How are x and a are ending up the same? Â I would think .copy() would > make it completely seperate. Nope, .copy() only makes a "shallow" copy of the outermost dict, not a recursive "deep" copy; the 2 dictionaries initially point to the *exact* same objects for their keys and values. a = x.copy() assert x is not a # wouldn't be much of a copy otherwise assert x["data"] is a["data"] # no recursive copying though # separate dicts, so rebinding the items of one doesn't affect the other x[42] = 12 assert 42 not in a # mutating the items in one does affect the other however x["data"].append(7) assert a["data"].pop() == 7 # remember that x[y] = z === x.__setitem__(y, z) # so we can write a similar example thusly: x["data"][0] = 8 assert a["data"][0] == 8 # again, rebinding at the outermost level is independent x["data"] = 99 assert a["data"] != x["data"] For a deep copy, use copy.deepcopy() in the std lib: http://docs.python.org/library/copy.html#copy.deepcopy Cheers, Chris -- http://blog.rebertia.com
|
Pages: 1 Prev: Constructor call in the same class? Next: obtaining pid of child process |