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?
Python follows the same precedence rules for its mathematical operators that mathematics does. Parentheses have the highest precedence and can be used to force an expression to evaluate in the order you want. Since expressions in parentheses are evaluated first, 2 * (3-1) is 4, and (1+1)**(5-2) is 8.
The new Assignment expression (:=) operator from Python 3.8 onwards has the lowest precedence while parentheses() have the highest precedence.
Associativity is the order in which an expression with multiple operators of the same precedence is evaluated. Associativity can be either from left to right or right to left. Almost all the operators have left-to-right associativity, except a few.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With