You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Fix evaluation order of keys/values in dict comprehensions #73838
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2019-09-17.23:36:16.137>created_at=<Date2017-02-25.19:54:43.014>labels= ['interpreter-core', 'type-bug', '3.8']
title='Fix evaluation order of keys/values in dict comprehensions'updated_at=<Date2019-09-17.23:36:16.137>user='https://github.com/DimitrisJim'
Currently the evaluation order for keys and values in a dictionary comprehension follows that of assignments. The values get evaluated first and then the keys:
This seems to conflict with the semantics as described in the Semantics section of PEP-274 [2] and according to my interpretation of the reference manual (I'd expect the evaluation to be similar to dict-displays).
How should this be addressed? Fix the evaluation order or specify this edge case an "Implementation detail" in the reference manual?
I already have a fix for this lying around (changes to compiler_sync_comprehension_generator, compiler_sync_comprehension_generator and a switch in MAP_ADD) and can make a pull request if required.
I'm not sure if this is classified as a bug per-se so I only tagged Py3.7 for it.
I think the current behavior is correct and desirable (as you say, it follows the order that would take place in an assignment, making it easy to roll-up existing for-loop code into a dict comprehension or to unroll and existing comprehension). Also, I think changing the behavior might risk introducing bugs into existing code that may have unconsciously relied on the existing order. My recommendation is to document the current value-first behavior.
For the other issue, 11205, I agree with the discussion there that key-first-value-second makes more sense in the context of literals which are normally evaluated left-to-right.
The current discrepancy is odd when you compare it to the equivalent generator expression:
{k:v for k, v in iterable}
dict(((k, v) for k, v in iterable))
It would never have occurred to me to expect the evaluation order to match a fully unrolled loop with a nested "d[k] = v" assignment, because the dict constructor doesn't work that way - it accepts an iterable of 2-tuples.
Just as a note so the email discussion isn't forever lost to the void.
In an unrelated thread on python-dev recently there was a short discussion on this topic in which both Guido van Rossum[1] and Tim Peters[2] gave the opinion that this should change should probably be made.
Activity
DimitrisJim commentedon Feb 25, 2017
Reported from [1] and similar to bpo-11205
Currently the evaluation order for keys and values in a dictionary comprehension follows that of assignments. The values get evaluated first and then the keys:
This seems to conflict with the semantics as described in the Semantics section of PEP-274 [2] and according to my interpretation of the reference manual (I'd expect the evaluation to be similar to dict-displays).
How should this be addressed? Fix the evaluation order or specify this edge case an "Implementation detail" in the reference manual?
I already have a fix for this lying around (changes to
compiler_sync_comprehension_generator,compiler_sync_comprehension_generatorand a switch inMAP_ADD) and can make a pull request if required.I'm not sure if this is classified as a bug per-se so I only tagged Py3.7 for it.
[1] http://stackoverflow.com/questions/42201932/order-of-operations-in-a-dictionary-comprehension
[2] https://www.python.org/dev/peps/pep-0274/#semantics
rhettinger commentedon Feb 27, 2017
I think the current behavior is correct and desirable (as you say, it follows the order that would take place in an assignment, making it easy to roll-up existing for-loop code into a dict comprehension or to unroll and existing comprehension). Also, I think changing the behavior might risk introducing bugs into existing code that may have unconsciously relied on the existing order. My recommendation is to document the current value-first behavior.
For the other issue, 11205, I agree with the discussion there that key-first-value-second makes more sense in the context of literals which are normally evaluated left-to-right.
ncoghlan commentedon Apr 27, 2018
The current discrepancy is odd when you compare it to the equivalent generator expression:
It would never have occurred to me to expect the evaluation order to match a fully unrolled loop with a nested "d[k] = v" assignment, because the dict constructor doesn't work that way - it accepts an iterable of 2-tuples.
PEP-274 also specifies the iterable-of-2-tuples interpretation (using a list comprehension as its baseline rather than a generator expression): https://www.python.org/dev/peps/pep-0274/#semantics
Janzert commentedon Apr 29, 2018
Just as a note so the email discussion isn't forever lost to the void.
In an unrelated thread on python-dev recently there was a short discussion on this topic in which both Guido van Rossum[1] and Tim Peters[2] gave the opinion that this should change should probably be made.
1: https://mail.python.org/pipermail/python-dev/2018-April/153122.html
2: https://mail.python.org/pipermail/python-dev/2018-April/153134.html
DimitrisJim commentedon Sep 3, 2019
This was indeed changed as part of PEP-572. Should be closed as fixed.