I saw this Python snippet on Twitter and was quite confused by the output:
>>> a, b = a[b] = {}, 5
>>> a
{5: ({...}, 5)}
What is going on here?
I saw this Python snippet on Twitter and was quite confused by the output:
>>> a, b = a[b] = {}, 5
>>> a
{5: ({...}, 5)}
What is going on here?
From the Assignment statements documentation:
An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.
You have two assignment target lists; a, b
, and a[b]
, the value {}, 5
is assigned to those two targets from left to right.
First the {}, 5
tuple is unpacked to a, b
. You now have a = {}
and b = 5
. Note that {}
is mutable.
Next you assign the same dictionary and integer to a[b]
, where a
evaluates to the dictionary, and b
evaluates to 5
, so you are setting the key 5
in the dictionary to the tuple ({}, 5)
creating a circular reference. The {...}
thus refers to the same object that a
is already referencing.
Because assignment takes place from left to right, you can break this down to:
a, b = {}, 5
a[b] = a, b
so a[b][0]
is the same object as a
:
>>> a, b = {}, 5
>>> a[b] = a, b
>>> a
{5: ({...}, 5)}
>>> a[b][0] is a
True
a[b][0] is a
line. –
Petitioner a, b = {}, 5; a[b] = {}, 5
? –
Priscella {}, 5
to be evaluated twice when assigning? Why should it be? {}
is still the same object. It's the equivalent of d = {}; a, b = d, 5; a[b] = d, 5
. –
Henrieta tmp0, tmp1 = {}, 5; a, b = tmp0, tmp1; a[b] = tmp0, tmp1
, so that there won't be a circular reference. –
Priscella a
is just a reference to {}
, which is mutable! So even in tmp0, tmp1 = {}, 5; a, b = tmp0, tmp1; a[b] = tmp0, tmp1
, the value (or "referenced object") of a
is still {5: ({...}, 5)}
–
Priscella © 2022 - 2024 — McMap. All rights reserved.
NameError
, witha[b] = a, b = {}, 5
working. – Strawberry