== What's going on with a Python assignment puzzle Via [[@chneukirchen https://twitter.com/chneukirchen]], I ran across [[this tweet https://twitter.com/cfbolz/status/634279681043394560]]: > Armin just came up with this puzzle, how well do you know obscure > Python details? What's a after this statement?: \\ > (a, b) = a[b] = {}, 5 This is best run interactively for maximum head-scratching. I had to run it in an interpreter myself and then think for a while, because there are several interesting Python things going on here. Let's start by removing the middle assignment. That gives us: > (a, b) = {}, 5 This is Python's multiple variable assignment ('_x, y = 10, 20_') written to make the sequence nature of the variable names explicit (hence why the Python tutorial calls this [['sequence unpacking' https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences]]). Writing the list of variables as an explicit tuple (or list) is optional but is something [[even I've done sometimes UsingTempfile]], although I think writing it this way has fallen out of favour. Thus it's equivalent to: > t = ({}, 5) > (a, b) = t The next trick is that (somewhat to my surprise) when you're assigning a tuple to several variables at once (as '_x = y = 10_') and doing sequence unpacking for one of those assignments, Python doesn't require you to do sequence unpacking for every assignment. The following is valid: > (a, b) = x = t Here _a_ and _b_ become the individual elements of the tuple _t_ while _x_ is the whole tuple. I suppose this is a useful trick to remember if you sometimes want both the tuple and its elements for different purposes. The next trick happening is that Python explicitly handles repeated variable assignment (sometimes called 'chained assignment' or 'serial assignment') in left to right order. So first the leftmost set of assignments are handled, and second the next leftmost, and so on. Here we only have two sets of assignments, so the entire statement is equivalent to the much more verbose form: > t = ({}, 5) > (a, b) = t > a[b] = t (When you do this outside of a function, the first (leftmost) assignment also creates _a_ and _b_ as names, which means that the second (right) assignment then has them available to use and doesn't get a 'name is not defined' error.) The final 'trick' is due to [[what variables mean in Python WhatVariablesMean]], which creates the recursion in _a[b]_'s value. The tuple _t_ that winds up assigned to _a[b]_ contains a reference to the dictionary that _a_ becomes another reference to, which means that the tuple contains a dictionary that contains the tuple again and it's recursion all the way down. (When you combine Python's [[name binding WhatVariablesMean]] behavior with serial assignment like this, [[you can wind up with fun bugs APythonCodingMistake]].)