Oct-07-2023, 04:37 PM
(This post was last modified: Oct-07-2023, 04:37 PM by Gribouillis.)
I came across the following bug
But this is not what happened! Here is a more detailed version
The dis module explains what's going on
What should I have done?
D = dict() D = D['spam'] = dict()I expected that
D['spam'] = dict() would create a new dictionary as a value in D, then the D = part would reassign the variable D as this new empty dictionary.But this is not what happened! Here is a more detailed version
>>>
>>> D = dict()
>>> X = D
>>> D = D['spam'] = dict()
>>> D
{'spam': {...}} # Hey! dictionary D is not empty. It has a key 'spam'
>>> D is D['spam'] # What? D['spam'] is D itself! D is a cyclic object that contains itself
True
>>> X is D
False
>>> X
{} # X is still the empty dictionary that we created at the beginningExplanationThe dis module explains what's going on
>>> import dis
>>> dis.dis('D = D["spam"] = dict()')
1 0 LOAD_NAME 0 (dict)
2 CALL_FUNCTION 0 # The dict() function is called and its result is on top of the stack
4 DUP_TOP # The top of the stack is duplicated!
6 STORE_NAME 1 (D) # the top element is consumed and assigned to D: from left to right
8 LOAD_NAME 1 (D)
10 LOAD_CONST 0 ('spam')
12 STORE_SUBSCR # the duplicated top element is consumed and assigned to D['spam']
14 LOAD_CONST 1 (None)
16 RETURN_VALUE
>>> Conclusion: when we writea = b = c = d = valueit is equivalent, in this order to
a = value b = value c = value d = valueWhen
b is a['spam'] it is the new a that is used for the second assignment!What should I have done?
D['spam'] = D = dict()Proof
>>> D = dict()
>>> X = D
>>> D['spam'] = D = dict()
>>> D
{}
>>> X
{'spam': {}}
>>> X['spam'] is D
True
