New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix evaluation order of keys/values in dict comprehensions #73838
Comments
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: def printer(v):
print(v, end=' ')
return v
d = {printer(i): printer(j) for i, j in [(1, 2), (3, 4)]}
# 2 1 4 3 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 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 |
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:
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 |
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 |
This was indeed changed as part of PEP-572. Should be closed as fixed. |
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:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: