Issue 29652: Fix evaluation order of keys/values in dict comprehensions (original) (raw)
Issue29652
Created on 2017-02-25 19:54 by Jim Fasarakis-Hilliard, last changed 2022-04-11 14:58 by admin. This issue is now closed.
Messages (5) | ||
---|---|---|
msg288578 - (view) | Author: Jim Fasarakis-Hilliard (Jim Fasarakis-Hilliard) * | Date: 2017-02-25 19:54 |
Reported from [1] and similar to 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 `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. [1] http://stackoverflow.com/questions/42201932/order-of-operations-in-a-dictionary-comprehension [2] https://www.python.org/dev/peps/pep-0274/#semantics | ||
msg288623 - (view) | Author: Raymond Hettinger (rhettinger) * ![]() |
Date: 2017-02-27 09:35 |
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. | ||
msg315832 - (view) | Author: Alyssa Coghlan (ncoghlan) * ![]() |
Date: 2018-04-27 10:01 |
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. 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 | ||
msg315874 - (view) | Author: janzert (janzert) * | Date: 2018-04-29 01:15 |
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 | ||
msg351088 - (view) | Author: Jim Fasarakis-Hilliard (Jim Fasarakis-Hilliard) * | Date: 2019-09-03 15:16 |
This was indeed changed as part of PEP 572. Should be closed as fixed. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:58:43 | admin | set | github: 73838 |
2019-09-17 23:36:16 | brett.cannon | set | status: closedresolution: fixedstage: resolved |
2019-09-03 15:16:25 | Jim Fasarakis-Hilliard | set | status: open -> (no value)messages: + |
2018-04-29 01:15:39 | janzert | set | nosy: + janzertmessages: + |
2018-04-27 10:01:37 | ncoghlan | set | nosy: + ncoghlanmessages: + versions: + Python 3.8, - Python 3.7 |
2017-02-27 09:35:03 | rhettinger | set | nosy: + rhettingermessages: + |
2017-02-27 08:39:13 | EvKounis | set | nosy: + EvKounis |
2017-02-26 13:14:41 | xiang.zhang | set | nosy: + xiang.zhang |
2017-02-25 19:54:43 | Jim Fasarakis-Hilliard | create |