This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: "as" keyword in comprehensions
Type: enhancement Stage: resolved
Components: Versions: Python 3.7
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: brett.cannon, nemeskeyd, rhettinger
Priority: normal Keywords:

Created on 2017-05-25 08:13 by nemeskeyd, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (5)
msg294446 - (view) Author: Dávid Nemeskey (nemeskeyd) Date: 2017-05-25 08:13
Currently, the "as" keyword in supported in import and with statements to bind an object to a name. I think it would be nice to have the same functionality in list/dict/etc. comprehensions as well.

Rationale: as I understand, comprehensions are preferred over map/filter + lambdas for creating modified versions of sequences (etc.) in Python. They are indeed useful for replacing map, filter, or map(filter); however, filter(map) is currently not supported. This is not an unusual use-case, as the two examples below show. It is also evident that they are very wordy with lambdas, and could be much clearer with comprehensions:

    with open(file) as inf:
        lines = list(filter(lambda l: l, map(lambda line: line.strip(), inf)))
    items = dict(filter(lambda kv: kv[1] > 5,
                        map(lambda kv: kv[0], len(kv[1]), d.items())))

Currently the only way to do this with comprehensions are:

    with open(file) as inf:
        lines = [l for l in (line.strip() for line in inf) if l]
    items = {k: v for k, v in ((k, len(v)) for k, v in d.items()) if v > 5)}

, or

    items = {k: len(v) for k, v in d.items() if len(v) > 5}

The first option is as unwieldy and unreadable as the code with lambdas, while the second is ineffective as it calls len() twice (and of course here len() is just a placeholder for a potentially heavy operation).

I propose to allow the "as" keyword in comprehensions as well to bind the result of an operation in the output expression to a name that could be used in the optional predicate. In other words, provide a let-like functionality. Like so:

    with open(file) as inf:
        lines = [line.strip() as l for line in inf if l]
    items = {(k, len(v) as lenv) for k, v in d.items() if lenv > 5}
msg294514 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2017-05-25 21:43
The best place to propose this is on the python-ideas mailing list. My suspicion, though, is people will say it's not worth the new syntax as you can also undo your comprehensions as normal code and simply assign to a variable name directly.
msg294524 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2017-05-26 02:29
As Brett says, the place to propose this is on python-ideas.  

I'm going to mark it here as closed/rejected because it will likely have to go through a lengthy process (possibly including a PEP) before having a chance of being accepted.  Please don't take this as discouragement.  It is just that the tracker is the wrong forum for the conversation to start.

On the plus side, the idea does seem like a nice convenience.  On the minus side, we really like that inconveniences serve as a nudge to not put too much inside a list comprehension and use a regular for-loop instead.  Also, Guido in the past has resisted similar suggestions for making assignments inside a while-loop conditional expression ("while (f.read(10) as block) != '': ...).
msg294543 - (view) Author: Dávid Nemeskey (nemeskeyd) Date: 2017-05-26 10:00
The truth is, I was thinking about going to the list, but according to PEP 42 (https://www.python.org/dev/peps/pep-0042/), this space was one of the places new features could be requested:

"""
Note

This PEP has been rejected as obsolete. All new feature requests should either go to the Python bug tracker [1] or the python-ideas [2] mailing list. The rest of this document is retained for historical purposes only.
"""

Going to the list, then.
msg294561 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2017-05-26 18:07
I've created https://github.com/python/peps/pull/267 to clarify things a bit better in PEP 42, Dávid .
History
Date User Action Args
2022-04-11 14:58:46adminsetgithub: 74656
2017-05-26 18:07:40brett.cannonsetmessages: + msg294561
2017-05-26 10:00:52nemeskeydsetmessages: + msg294543
2017-05-26 02:29:58rhettingersetstatus: open -> closed

versions: + Python 3.7
nosy: + rhettinger

messages: + msg294524
resolution: rejected
stage: resolved
2017-05-25 21:43:39brett.cannonsetnosy: + brett.cannon
messages: + msg294514
2017-05-25 08:13:59nemeskeydcreate