It has already been explained what {...}
means here, so I'll try to answer the question: Why is a[0]
assigned a self-reference and not another instance of {'a': 1}
?
First, note that we have the same behaviour if we do x = y = []
: x
and y
are assigned the same list, and not two different empty lists:
>>> x = y = []
>>> x.append(1)
>>> y
[1]
Why does this happen? Let's have a look at the disassembly:
>>> import dis
>>> dis.dis("a = a[0] = {'a': 1}")
1 0 LOAD_CONST 0 ('a')
2 LOAD_CONST 1 (1)
4 BUILD_MAP 1
6 DUP_TOP
8 STORE_NAME 0 (a)
10 LOAD_NAME 0 (a)
12 LOAD_CONST 2 (0)
14 STORE_SUBSCR
16 LOAD_CONST 3 (None)
18 RETURN_VALUE
(You can ignore the last two lines, they are not relevant to the assignment.) The first three lines create the map {'a': 1}
, then DUP_TOP
duplicates the reference to that map, then that reference is stored in both a
and a[0]
.
Thus, the assignment can roughly be interpreted as tmp = {'a': 1}; a = tmp; a[0] = tmp