a = b = random.random()
I would not expect a and b to get different values. It would be very strange if using `[]` had different behavior than a function call in the same place. Am I out of step here?A somewhat trickier example of the same issue is using [] as a default parameter value ... though there are warnings about the problem with that (it's the same list on every call) throughout the documentation.
a = b = []
has the same semantics here as b = []
a = b
which I don't find surprising.Is chained assignment a pattern that comes from another language that people are applying to python?
a, b = b[a] = 1, [0, 1, 2, 3]It's unusual, but pretty obvious. In single steps it's basically this:
a, b = 1, [0, 1, 2, 3]
b[a] = b
which would be b[1]=b because a==1. So this creates a self referencing list. The deeper reason here is, everything is a pointer to data in memory, even if in source code we see the actual data. That's why b[1] is storing the pointer to the list, not the data of the list.If someone is doing BS like this, they deserve spanking. But banning the whole concept because people are unaware or how something is to be used properly is strange. But then again, it seems people have a bit of a problem how python really works and how it's different from other languages.
0, (1, [...]), 2, 3]
vs your version: [0, [...], 2, 3]
The equivalent statements to the original chained assignment are: a, b = 1, [0, 1, 2, 3]
b[a] = 1, b # relies on cpython implementation detail¹
¹: Using 1 works because the integers -5 thru 256 are interned in cpython. Otherwise, or if you don't want to rely on an implementation detail, to be truly equivalent (i.e. `id(b[1][0]) == id(a)`), it's this: a, b = 1, [0, 1, 2, 3]
b[a] = a, bThat said, it's the self-referencing list in your example that's the more confusing part. It's atypical to have self-referencing data structures, so that's something I'd comment in the design if I needed one.
Ummm no the list is constructed once and assigned to b and then b is assigned to a. It would be crazy semantics if `a = b = ...` meant `a` was assigned `...`.
Edit: I'm wrong it's left to right not right to left, which makes the complaint in the article even dumber.
> An assignment statement evaluates the expression list and assigns the single resulting object to each of the target lists, from left to right.
Consider this:
a = [1, 2]
i = a[i] = 1
If assignment were to happen right to left, you would get a NameError exception because the first assignment would require an unbound variable.Wouldn't that require a LOAD_FAST? Also a is assigned first (from left to right) so a = ... happens either way.