I just recently came across this cool hack in Python.
This:
d = {}
for i, d[i] in enumerate('abc'):
pass
>>> d
{0: 'a', 1: 'b', 2: 'c'}
>>>
This assigns key value pairs to a empty dictionary from the iterator.
I would like to know how Cython backend parses this, my expectation is that it's being parsed with unpacking assignment. But it would be nice to know the actual Cython implementation of this, and also if doing this is recommended or not?
I know I just can simply do:
d = {}
for i, v in enumerate('abc'):
d[i] = v
But the cool hack above can do this with shorter code, but I am not sure if it is considered good practice in Python.
I never seen anybody use this...
You don't have to read CPython code since the behavior is defined in the Python documentation already.
If you read the documentation of the for statement, the target list in a for
statement uses rules of a standard assignment:
Each item in turn is assigned to the target list using the standard rules for assignments (see Assignment statements)
And if you read the rules for assignment statements, you can see that each item in the target list of an assignment is assigned to in a left-to-right order:
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.
So in the first iteration of your for
loop, where a tuple 0, 'a'
is generated:
for i, d[i] in enumerate('abc')
An assignment statement equivalent to the following is executed:
i, d[i] = 0, 'a'
which assigns 0
to i
first since it's on the left, and then 'a'
to d[i]
, which evaluates to d[0]
, effectively making d[0] = 'a'
.
The same goes for the rest of the iterations.