I'm not sure if I'm missing something trivially obvious here but I can't for the life of me work out how the code below manages to give the output it does.
import collections
tree = collections.defaultdict(dict)
tree[0][1] = tree[1]
print tree
tree[1][2] = tree[2]
print tree
And here's the magical output:
defaultdict(<type 'dict'>, {0: {1: {}}, 1: {}})
defaultdict(<type 'dict'>, {0: {1: {2: {}}}, 1: {2: {}}, 2: {}})
The first line of output makes total sense. Consider then, the assignment tree[1][2] = tree[2]
and its subsequent output.
I understand that the entry 2: {}
has been created by evaluating the RHS expression tree[2]
.
I also understand the the entry 1: {2: {}}
is created be evaluating the LHS expression tree[1][2]
and assigning it to the value of the RHS.
What I don't understand, is how the dictionary entry 0: {1: {}}
has been updated to 0: {1: {2: {}}}
when no reference to tree[0]
was made.
Because when you do tree[0][1] = tree[1]
, tree[0][1]
is referencing the same object as tree[1]
, so if any changes happen inside tree[1]
, it will also reflect in tree[0][1]
.
And, when you do tree[1][2]
, you are actually making changes inside tree[1]
, and not making tree[1]
reference a new object.
Example , after your changes try to do this -
>>> tree[1]['blah'] = 'Hello'
>>> print(tree)
defaultdict(<class 'dict'>, {0: {1: {2: {}, 'blah': 'Hello'}}, 1: {2: {}, 'blah': 'Hello'}, 2: {}})
Only if you do something like - tree[1] = <somethingelse>
, you are making tree[1]
reference a new object, in which case it would not reflect in tree[0][1]
.