Using Key Value Pair Assignments For A Dictionary As An Iterator In A For Loop
Solution 1:
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:
fori, d[i]inenumerate('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.
Solution 2:
@blhsing already explained that it's ordinary left-to-right assignment. I've sometimes done this and similar variations, and I'd like to add why:
- Brevity. It's slightly shorter, even when your extra variable is only one letter.
- Speed. It avoids pointless storing and loading of a variable.
- Cleanliness. Doesn't pollute the namespace with a pointless variable.
- Laziness. Don't want to have to think of a variable name. That's hard.
- Education. I like pointing out things that people aren't familiar with :-)
- Entertainment. Related to the previous point - I like to puzzle people :-D
So to answer your "recommended or not?" and whether it's "considered good practice": I'd say yes, I think it's perfectly fine and even has advantages. The only potential downside I see is that some people might complain about it purely because they're not familiar with it and don't like unfamiliar things.
About the speed aspect: As shown with dis.dis
below, everything's the same for both versions except for the additional STORE and LOAD of the extra variable v
.
dis.dis(''' | dis.dis('''
d = {} | d = {}
for i, d[i] inenumerate('abc'): | for i, v inenumerate('abc'):
pass | d[i] = v
''') | ''')
----------------------------------+-----------------------------------
0 BUILD_MAP 0 | 0 BUILD_MAP 02 STORE_NAME 0 (d) | 2 STORE_NAME 0 (d)
4 LOAD_NAME 1 (enumerate) | 4 LOAD_NAME 1 (enumerate)
6 LOAD_CONST 0 ('abc') | 6 LOAD_CONST 0 ('abc')
8 CALL_FUNCTION 1 | 8 CALL_FUNCTION 110 GET_ITER | 10 GET_ITER
12 FOR_ITER 12 (to 26) | 12 FOR_ITER 16 (to 30)
14 UNPACK_SEQUENCE 2 | 14 UNPACK_SEQUENCE 216 STORE_NAME 2 (i) | 16 STORE_NAME 2 (i)
| 18 STORE_NAME 3 (v)
| 20 LOAD_NAME 3 (v)
18 LOAD_NAME 0 (d) | 22 LOAD_NAME 0 (d)
20 LOAD_NAME 2 (i) | 24 LOAD_NAME 2 (i)
22 STORE_SUBSCR | 26 STORE_SUBSCR
24 JUMP_ABSOLUTE 12 | 28 JUMP_ABSOLUTE 1226 LOAD_CONST 1 (None) | 30 LOAD_CONST 1 (None)
28 RETURN_VALUE | 32 RETURN_VALUE
Post a Comment for "Using Key Value Pair Assignments For A Dictionary As An Iterator In A For Loop"